From 8cac53f6f5a2c259548a7c6fe23a743b25895471 Mon Sep 17 00:00:00 2001 From: Dan Gowans Date: Wed, 3 Jul 2024 09:56:28 -0400 Subject: [PATCH] simplify client js --- gulpfile.js | 48 +- gulpfile.ts | 77 +- package-lock.json | 504 +-- package.json | 11 +- public-typescript/adminTables.js | 726 ----- public-typescript/adminTables/adminTables.js | 23 - public-typescript/adminTables/adminTables.ts | 36 - .../adminTablesLotOccupantTypes.d.ts | 1 - .../adminTablesLotOccupantTypes.js | 204 -- .../adminTablesLotOccupantTypes.ts | 292 -- .../adminTables/adminTablesLotStatuses.d.ts | 1 - .../adminTables/adminTablesLotStatuses.js | 167 - .../adminTables/adminTablesLotStatuses.ts | 248 -- .../adminTablesWorkOrderMilestoneTypes.d.ts | 1 - .../adminTablesWorkOrderMilestoneTypes.js | 166 - .../adminTablesWorkOrderMilestoneTypes.ts | 250 -- .../adminTablesWorkOrderTypes.d.ts | 1 - .../adminTables/adminTablesWorkOrderTypes.js | 166 - .../adminTables/adminTablesWorkOrderTypes.ts | 247 -- public-typescript/lotOccupancyEdit.js | 1729 ---------- .../lotOccupancyEdit/lotOccupancyEdit.js | 481 --- .../lotOccupancyEdit/lotOccupancyEdit.ts | 753 ----- .../lotOccupancyEditComments.d.ts | 1 - .../lotOccupancyEditComments.js | 185 -- .../lotOccupancyEditComments.ts | 305 -- .../lotOccupancyEditFees.d.ts | 1 - .../lotOccupancyEdit/lotOccupancyEditFees.js | 671 ---- .../lotOccupancyEdit/lotOccupancyEditFees.ts | 1054 ------- .../lotOccupancyEditOccupants.d.ts | 1 - .../lotOccupancyEditOccupants.js | 392 --- .../lotOccupancyEditOccupants.ts | 693 ---- public-typescript/workOrderEdit.js | 1259 -------- .../workOrderEdit/workOrderEdit.js | 525 ---- .../workOrderEdit/workOrderEdit.ts | 826 ----- .../workOrderEdit/workOrderEditComments.d.ts | 1 - .../workOrderEdit/workOrderEditComments.js | 182 -- .../workOrderEdit/workOrderEditComments.ts | 295 -- .../workOrderEdit/workOrderEditLots.d.ts | 1 - .../workOrderEdit/workOrderEditLots.js | 552 ---- .../workOrderEdit/workOrderEditLots.ts | 847 ----- .../javascripts}/adminDatabase.d.ts | 0 .../javascripts}/adminDatabase.js | 0 public/javascripts/adminDatabase.min.js | 1 - .../javascripts}/adminDatabase.ts | 2 +- .../javascripts}/adminFees.d.ts | 0 .../javascripts}/adminFees.js | 0 public/javascripts/adminFees.min.js | 1 - .../javascripts}/adminFees.ts | 4 +- .../javascripts}/adminLotTypes.d.ts | 0 .../javascripts}/adminLotTypes.js | 0 public/javascripts/adminLotTypes.min.js | 1 - .../javascripts}/adminLotTypes.ts | 4 +- .../javascripts}/adminOccupancyTypes.d.ts | 0 .../javascripts}/adminOccupancyTypes.js | 0 public/javascripts/adminOccupancyTypes.min.js | 1 - .../javascripts}/adminOccupancyTypes.ts | 4 +- .../javascripts}/adminTables.d.ts | 0 public/javascripts/adminTables.js | 714 +++++ public/javascripts/adminTables.min.js | 1 - public/javascripts/adminTables.ts | 1043 ++++++ .../javascripts}/dashboard.d.ts | 0 .../javascripts}/dashboard.js | 0 public/javascripts/dashboard.min.js | 1 - .../javascripts}/dashboard.ts | 2 +- .../javascripts}/lotEdit.d.ts | 0 .../javascripts}/lotEdit.js | 0 public/javascripts/lotEdit.min.js | 1 - .../javascripts}/lotEdit.ts | 4 +- .../javascripts}/lotOccupancyEdit.d.ts | 0 public/javascripts/lotOccupancyEdit.js | 1736 ++++++++++ public/javascripts/lotOccupancyEdit.min.js | 1 - public/javascripts/lotOccupancyEdit.ts | 2797 +++++++++++++++++ .../javascripts}/lotOccupancySearch.d.ts | 0 .../javascripts}/lotOccupancySearch.js | 0 public/javascripts/lotOccupancySearch.min.js | 1 - .../javascripts}/lotOccupancySearch.ts | 4 +- .../javascripts}/lotSearch.d.ts | 0 .../javascripts}/lotSearch.js | 0 public/javascripts/lotSearch.min.js | 1 - .../javascripts}/lotSearch.ts | 4 +- .../javascripts}/lotView.d.ts | 0 .../javascripts}/lotView.js | 0 public/javascripts/lotView.min.js | 1 - .../javascripts}/lotView.ts | 2 +- .../javascripts}/main.d.ts | 0 .../javascripts}/main.js | 0 public/javascripts/main.min.js | 1 - .../javascripts}/main.ts | 2 +- .../javascripts}/mapEdit.d.ts | 0 .../javascripts}/mapEdit.js | 0 public/javascripts/mapEdit.min.js | 1 - .../javascripts}/mapEdit.ts | 2 +- .../javascripts}/mapSearch.d.ts | 0 .../javascripts}/mapSearch.js | 0 public/javascripts/mapSearch.min.js | 1 - .../javascripts}/mapSearch.ts | 4 +- .../javascripts}/mapView.d.ts | 0 .../javascripts}/mapView.js | 0 public/javascripts/mapView.min.js | 1 - .../javascripts}/mapView.ts | 0 .../javascripts}/reportSearch.d.ts | 0 .../javascripts}/reportSearch.js | 0 public/javascripts/reportSearch.min.js | 1 - .../javascripts}/reportSearch.ts | 0 .../javascripts}/workOrderEdit.d.ts | 0 public/javascripts/workOrderEdit.js | 1257 ++++++++ public/javascripts/workOrderEdit.min.js | 1 - public/javascripts/workOrderEdit.ts | 1953 ++++++++++++ .../workOrderMilestoneCalendar.d.ts | 0 .../workOrderMilestoneCalendar.js | 0 .../workOrderMilestoneCalendar.min.js | 1 - .../workOrderMilestoneCalendar.ts | 4 +- .../javascripts}/workOrderOutlook.d.ts | 0 .../javascripts}/workOrderOutlook.js | 0 public/javascripts/workOrderOutlook.min.js | 1 - .../javascripts}/workOrderOutlook.ts | 2 +- .../javascripts}/workOrderSearch.d.ts | 0 .../javascripts}/workOrderSearch.js | 0 public/javascripts/workOrderSearch.min.js | 1 - .../javascripts}/workOrderSearch.ts | 4 +- .../javascripts}/workOrderView.d.ts | 0 .../javascripts}/workOrderView.js | 0 public/javascripts/workOrderView.min.js | 1 - .../javascripts}/workOrderView.ts | 2 +- tsconfig.client.json | 47 +- tsconfig.json | 2 +- views/_footerA.ejs | 2 +- views/admin-database.ejs | 2 +- views/admin-fees.ejs | 2 +- views/admin-lotTypes.ejs | 2 +- views/admin-occupancyTypes.ejs | 2 +- views/admin-tables.ejs | 2 +- views/dashboard.ejs | 2 +- views/lot-edit.ejs | 2 +- views/lot-search.ejs | 2 +- views/lot-view.ejs | 2 +- views/lotOccupancy-edit.ejs | 786 ++--- views/lotOccupancy-search.ejs | 254 +- views/map-edit.ejs | 2 +- views/map-search.ejs | 2 +- views/map-view.ejs | 2 +- views/report-search.ejs | 2 +- views/workOrder-edit.ejs | 2 +- views/workOrder-milestoneCalendar.ejs | 2 +- views/workOrder-outlook.ejs | 2 +- views/workOrder-search.ejs | 2 +- views/workOrder-view.ejs | 2 +- 147 files changed, 10101 insertions(+), 14520 deletions(-) delete mode 100644 public-typescript/adminTables.js delete mode 100644 public-typescript/adminTables/adminTables.js delete mode 100644 public-typescript/adminTables/adminTables.ts delete mode 100644 public-typescript/adminTables/adminTablesLotOccupantTypes.d.ts delete mode 100644 public-typescript/adminTables/adminTablesLotOccupantTypes.js delete mode 100644 public-typescript/adminTables/adminTablesLotOccupantTypes.ts delete mode 100644 public-typescript/adminTables/adminTablesLotStatuses.d.ts delete mode 100644 public-typescript/adminTables/adminTablesLotStatuses.js delete mode 100644 public-typescript/adminTables/adminTablesLotStatuses.ts delete mode 100644 public-typescript/adminTables/adminTablesWorkOrderMilestoneTypes.d.ts delete mode 100644 public-typescript/adminTables/adminTablesWorkOrderMilestoneTypes.js delete mode 100644 public-typescript/adminTables/adminTablesWorkOrderMilestoneTypes.ts delete mode 100644 public-typescript/adminTables/adminTablesWorkOrderTypes.d.ts delete mode 100644 public-typescript/adminTables/adminTablesWorkOrderTypes.js delete mode 100644 public-typescript/adminTables/adminTablesWorkOrderTypes.ts delete mode 100644 public-typescript/lotOccupancyEdit.js delete mode 100644 public-typescript/lotOccupancyEdit/lotOccupancyEdit.js delete mode 100644 public-typescript/lotOccupancyEdit/lotOccupancyEdit.ts delete mode 100644 public-typescript/lotOccupancyEdit/lotOccupancyEditComments.d.ts delete mode 100644 public-typescript/lotOccupancyEdit/lotOccupancyEditComments.js delete mode 100644 public-typescript/lotOccupancyEdit/lotOccupancyEditComments.ts delete mode 100644 public-typescript/lotOccupancyEdit/lotOccupancyEditFees.d.ts delete mode 100644 public-typescript/lotOccupancyEdit/lotOccupancyEditFees.js delete mode 100644 public-typescript/lotOccupancyEdit/lotOccupancyEditFees.ts delete mode 100644 public-typescript/lotOccupancyEdit/lotOccupancyEditOccupants.d.ts delete mode 100644 public-typescript/lotOccupancyEdit/lotOccupancyEditOccupants.js delete mode 100644 public-typescript/lotOccupancyEdit/lotOccupancyEditOccupants.ts delete mode 100644 public-typescript/workOrderEdit.js delete mode 100644 public-typescript/workOrderEdit/workOrderEdit.js delete mode 100644 public-typescript/workOrderEdit/workOrderEdit.ts delete mode 100644 public-typescript/workOrderEdit/workOrderEditComments.d.ts delete mode 100644 public-typescript/workOrderEdit/workOrderEditComments.js delete mode 100644 public-typescript/workOrderEdit/workOrderEditComments.ts delete mode 100644 public-typescript/workOrderEdit/workOrderEditLots.d.ts delete mode 100644 public-typescript/workOrderEdit/workOrderEditLots.js delete mode 100644 public-typescript/workOrderEdit/workOrderEditLots.ts rename {public-typescript => public/javascripts}/adminDatabase.d.ts (100%) rename {public-typescript => public/javascripts}/adminDatabase.js (100%) delete mode 100644 public/javascripts/adminDatabase.min.js rename {public-typescript => public/javascripts}/adminDatabase.ts (98%) rename {public-typescript => public/javascripts}/adminFees.d.ts (100%) rename {public-typescript => public/javascripts}/adminFees.js (100%) delete mode 100644 public/javascripts/adminFees.min.js rename {public-typescript => public/javascripts}/adminFees.ts (99%) rename {public-typescript => public/javascripts}/adminLotTypes.d.ts (100%) rename {public-typescript => public/javascripts}/adminLotTypes.js (100%) delete mode 100644 public/javascripts/adminLotTypes.min.js rename {public-typescript => public/javascripts}/adminLotTypes.ts (99%) rename {public-typescript => public/javascripts}/adminOccupancyTypes.d.ts (100%) rename {public-typescript => public/javascripts}/adminOccupancyTypes.js (100%) delete mode 100644 public/javascripts/adminOccupancyTypes.min.js rename {public-typescript => public/javascripts}/adminOccupancyTypes.ts (99%) rename {public-typescript/adminTables => public/javascripts}/adminTables.d.ts (100%) create mode 100644 public/javascripts/adminTables.js delete mode 100644 public/javascripts/adminTables.min.js create mode 100644 public/javascripts/adminTables.ts rename {public-typescript => public/javascripts}/dashboard.d.ts (100%) rename {public-typescript => public/javascripts}/dashboard.js (100%) delete mode 100644 public/javascripts/dashboard.min.js rename {public-typescript => public/javascripts}/dashboard.ts (91%) rename {public-typescript => public/javascripts}/lotEdit.d.ts (100%) rename {public-typescript => public/javascripts}/lotEdit.js (100%) delete mode 100644 public/javascripts/lotEdit.min.js rename {public-typescript => public/javascripts}/lotEdit.ts (99%) rename {public-typescript/lotOccupancyEdit => public/javascripts}/lotOccupancyEdit.d.ts (100%) create mode 100644 public/javascripts/lotOccupancyEdit.js delete mode 100644 public/javascripts/lotOccupancyEdit.min.js create mode 100644 public/javascripts/lotOccupancyEdit.ts rename {public-typescript => public/javascripts}/lotOccupancySearch.d.ts (100%) rename {public-typescript => public/javascripts}/lotOccupancySearch.js (100%) delete mode 100644 public/javascripts/lotOccupancySearch.min.js rename {public-typescript => public/javascripts}/lotOccupancySearch.ts (98%) rename {public-typescript => public/javascripts}/lotSearch.d.ts (100%) rename {public-typescript => public/javascripts}/lotSearch.js (100%) delete mode 100644 public/javascripts/lotSearch.min.js rename {public-typescript => public/javascripts}/lotSearch.ts (97%) rename {public-typescript => public/javascripts}/lotView.d.ts (100%) rename {public-typescript => public/javascripts}/lotView.js (100%) delete mode 100644 public/javascripts/lotView.min.js rename {public-typescript => public/javascripts}/lotView.ts (89%) rename {public-typescript => public/javascripts}/main.d.ts (100%) rename {public-typescript => public/javascripts}/main.js (100%) delete mode 100644 public/javascripts/main.min.js rename {public-typescript => public/javascripts}/main.ts (99%) rename {public-typescript => public/javascripts}/mapEdit.d.ts (100%) rename {public-typescript => public/javascripts}/mapEdit.js (100%) delete mode 100644 public/javascripts/mapEdit.min.js rename {public-typescript => public/javascripts}/mapEdit.ts (98%) rename {public-typescript => public/javascripts}/mapSearch.d.ts (100%) rename {public-typescript => public/javascripts}/mapSearch.js (100%) delete mode 100644 public/javascripts/mapSearch.min.js rename {public-typescript => public/javascripts}/mapSearch.ts (97%) rename {public-typescript => public/javascripts}/mapView.d.ts (100%) rename {public-typescript => public/javascripts}/mapView.js (100%) delete mode 100644 public/javascripts/mapView.min.js rename {public-typescript => public/javascripts}/mapView.ts (100%) rename {public-typescript => public/javascripts}/reportSearch.d.ts (100%) rename {public-typescript => public/javascripts}/reportSearch.js (100%) delete mode 100644 public/javascripts/reportSearch.min.js rename {public-typescript => public/javascripts}/reportSearch.ts (100%) rename {public-typescript/workOrderEdit => public/javascripts}/workOrderEdit.d.ts (100%) create mode 100644 public/javascripts/workOrderEdit.js delete mode 100644 public/javascripts/workOrderEdit.min.js create mode 100644 public/javascripts/workOrderEdit.ts rename {public-typescript => public/javascripts}/workOrderMilestoneCalendar.d.ts (100%) rename {public-typescript => public/javascripts}/workOrderMilestoneCalendar.js (100%) delete mode 100644 public/javascripts/workOrderMilestoneCalendar.min.js rename {public-typescript => public/javascripts}/workOrderMilestoneCalendar.ts (98%) rename {public-typescript => public/javascripts}/workOrderOutlook.d.ts (100%) rename {public-typescript => public/javascripts}/workOrderOutlook.js (100%) delete mode 100644 public/javascripts/workOrderOutlook.min.js rename {public-typescript => public/javascripts}/workOrderOutlook.ts (97%) rename {public-typescript => public/javascripts}/workOrderSearch.d.ts (100%) rename {public-typescript => public/javascripts}/workOrderSearch.js (100%) delete mode 100644 public/javascripts/workOrderSearch.min.js rename {public-typescript => public/javascripts}/workOrderSearch.ts (98%) rename {public-typescript => public/javascripts}/workOrderView.d.ts (100%) rename {public-typescript => public/javascripts}/workOrderView.js (100%) delete mode 100644 public/javascripts/workOrderView.min.js rename {public-typescript => public/javascripts}/workOrderView.ts (97%) diff --git a/gulpfile.js b/gulpfile.js index 97986683..6a272c7f 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,11 +1,8 @@ // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair /* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return, n/no-unpublished-import */ import gulp from 'gulp'; -import changed from 'gulp-changed'; -import include from 'gulp-include'; -import minify from 'gulp-minify'; import gulpSass from 'gulp-sass'; -import dartSass from 'sass'; +import * as dartSass from 'sass'; const sass = gulpSass(dartSass); /* * Compile SASS @@ -20,60 +17,17 @@ function publicSCSSFunction() { .pipe(gulp.dest(publicSCSSDestination)); } gulp.task('public-scss', publicSCSSFunction); -/* - * Minify public/javascripts - */ -const publicJavascriptsDestination = 'public/javascripts'; -function publicJavascriptsMinFunction() { - return gulp - .src('public-typescript/*.js', { allowEmpty: true }) - .pipe(changed(publicJavascriptsDestination, { - extension: '.min.js' - })) - .pipe(minify({ noSource: true, ext: { min: '.min.js' } })) - .pipe(gulp.dest(publicJavascriptsDestination)); -} -function publicJavascriptsAdminTablesFunction() { - return gulp - .src('public-typescript/adminTables/adminTables.js') - .pipe(include()) - .pipe(gulp.dest('public-typescript')); -} -function publicJavascriptsLotOccupancyEditFunction() { - return gulp - .src('public-typescript/lotOccupancyEdit/lotOccupancyEdit.js') - .pipe(include()) - .pipe(gulp.dest('public-typescript')); -} -function publicJavascriptsWorkOrderEditFunction() { - return gulp - .src('public-typescript/workOrderEdit/workOrderEdit.js') - .pipe(include()) - .pipe(gulp.dest('public-typescript')); -} -gulp.task('public-javascript-adminTables', publicJavascriptsAdminTablesFunction); -gulp.task('public-javascript-lotOccupancyEdit', publicJavascriptsLotOccupancyEditFunction); -gulp.task('public-javascript-workOrderEdit', publicJavascriptsWorkOrderEditFunction); -gulp.task('public-javascript-min', publicJavascriptsMinFunction); /* * Watch */ function watchFunction() { gulp.watch('public-scss/*.scss', publicSCSSFunction); - gulp.watch('public-typescript/adminTables/*.js', publicJavascriptsAdminTablesFunction); - gulp.watch('public-typescript/lotOccupancyEdit/*.js', publicJavascriptsLotOccupancyEditFunction); - gulp.watch('public-typescript/workOrderEdit/*.js', publicJavascriptsWorkOrderEditFunction); - gulp.watch('public-typescript/*.js', publicJavascriptsMinFunction); } gulp.task('watch', watchFunction); /* * Initialize default */ gulp.task('default', () => { - publicJavascriptsAdminTablesFunction(); - publicJavascriptsLotOccupancyEditFunction(); - publicJavascriptsWorkOrderEditFunction(); - publicJavascriptsMinFunction(); publicSCSSFunction(); watchFunction(); }); diff --git a/gulpfile.ts b/gulpfile.ts index 5eaa6d68..5fcc04f8 100644 --- a/gulpfile.ts +++ b/gulpfile.ts @@ -2,11 +2,8 @@ /* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return, n/no-unpublished-import */ import gulp from 'gulp' -import changed from 'gulp-changed' -import include from 'gulp-include' -import minify from 'gulp-minify' import gulpSass from 'gulp-sass' -import dartSass from 'sass' +import * as dartSass from 'sass' const sass = gulpSass(dartSass) @@ -31,79 +28,12 @@ function publicSCSSFunction(): NodeJS.ReadWriteStream { gulp.task('public-scss', publicSCSSFunction) -/* - * Minify public/javascripts - */ - -const publicJavascriptsDestination = 'public/javascripts' - -function publicJavascriptsMinFunction(): NodeJS.ReadWriteStream { - return gulp - .src('public-typescript/*.js', { allowEmpty: true }) - .pipe( - changed(publicJavascriptsDestination, { - extension: '.min.js' - }) - ) - .pipe(minify({ noSource: true, ext: { min: '.min.js' } })) - .pipe(gulp.dest(publicJavascriptsDestination)) -} - -function publicJavascriptsAdminTablesFunction(): NodeJS.ReadWriteStream { - return gulp - .src('public-typescript/adminTables/adminTables.js') - .pipe(include()) - .pipe(gulp.dest('public-typescript')) -} - -function publicJavascriptsLotOccupancyEditFunction(): NodeJS.ReadWriteStream { - return gulp - .src('public-typescript/lotOccupancyEdit/lotOccupancyEdit.js') - .pipe(include()) - .pipe(gulp.dest('public-typescript')) -} - -function publicJavascriptsWorkOrderEditFunction(): NodeJS.ReadWriteStream { - return gulp - .src('public-typescript/workOrderEdit/workOrderEdit.js') - .pipe(include()) - .pipe(gulp.dest('public-typescript')) -} - -gulp.task('public-javascript-adminTables', publicJavascriptsAdminTablesFunction) -gulp.task( - 'public-javascript-lotOccupancyEdit', - publicJavascriptsLotOccupancyEditFunction -) -gulp.task( - 'public-javascript-workOrderEdit', - publicJavascriptsWorkOrderEditFunction -) -gulp.task('public-javascript-min', publicJavascriptsMinFunction) - /* * Watch */ function watchFunction(): void { gulp.watch('public-scss/*.scss', publicSCSSFunction) - - gulp.watch( - 'public-typescript/adminTables/*.js', - publicJavascriptsAdminTablesFunction - ) - - gulp.watch( - 'public-typescript/lotOccupancyEdit/*.js', - publicJavascriptsLotOccupancyEditFunction - ) - - gulp.watch( - 'public-typescript/workOrderEdit/*.js', - publicJavascriptsWorkOrderEditFunction - ) - - gulp.watch('public-typescript/*.js', publicJavascriptsMinFunction) } gulp.task('watch', watchFunction) @@ -113,11 +43,6 @@ gulp.task('watch', watchFunction) */ gulp.task('default', () => { - publicJavascriptsAdminTablesFunction() - publicJavascriptsLotOccupancyEditFunction() - publicJavascriptsWorkOrderEditFunction() - publicJavascriptsMinFunction() - publicSCSSFunction() watchFunction() diff --git a/package-lock.json b/package-lock.json index 0e6511fc..5c2798a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,7 @@ "@fortawesome/fontawesome-free": "^5.15.4", "activedirectory2": "^2.2.0", "better-sqlite-pool": "^0.3.2", - "better-sqlite3": "^11.1.1", + "better-sqlite3": "^11.1.2", "bulma-calendar": "^6.1.19", "camelcase": "^8.0.0", "compression": "^1.7.4", @@ -53,7 +53,7 @@ "@cityssm/mssql-multi-pool": "^3.1.5", "@cityssm/simple-fa5-checkbox": "^0.2.1", "@types/activedirectory2": "^1.2.6", - "@types/better-sqlite3": "^7.6.10", + "@types/better-sqlite3": "^7.6.11", "@types/compression": "^1.7.5", "@types/cookie-parser": "^1.4.7", "@types/csurf": "^1.11.5", @@ -62,8 +62,6 @@ "@types/express": "^4.17.21", "@types/express-session": "^1.18.0", "@types/gulp": "^4.0.17", - "@types/gulp-changed": "^0.0.39", - "@types/gulp-minify": "^3.1.5", "@types/gulp-sass": "^5.0.4", "@types/http-errors": "^2.0.4", "@types/leaflet": "^1.9.12", @@ -81,12 +79,9 @@ "bulma-steps": "^2.2.1", "bulma-switch": "^2.0.4", "bulma-tooltip": "^3.0.2", - "cypress": "^13.12.0", + "cypress": "^13.13.0", "cypress-axe": "^1.5.0", "gulp": "^5.0.0", - "gulp-changed": "^5.0.2", - "gulp-include": "^2.4.1", - "gulp-minify": "^3.1.0", "gulp-sass": "^5.1.0", "nodemon": "^3.1.4", "prettier-config-cityssm": "^1.0.0", @@ -1040,9 +1035,9 @@ } }, "node_modules/@types/better-sqlite3": { - "version": "7.6.10", - "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.10.tgz", - "integrity": "sha512-TZBjD+yOsyrUJGmcUj6OS3JADk3+UZcNv3NOBqGkM09bZdi28fNZw8ODqbMOLfKCu7RYCO62/ldq1iHbzxqoPw==", + "version": "7.6.11", + "resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.11.tgz", + "integrity": "sha512-i8KcD3PgGtGBLl3+mMYA8PdKkButvPyARxA7IQAd6qeslht13qxb1zzO8dRCtE7U3IoJS782zDBAeoKiM695kg==", "dev": true, "dependencies": { "@types/node": "*" @@ -1210,25 +1205,6 @@ "chokidar": "^3.3.1" } }, - "node_modules/@types/gulp-changed": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/gulp-changed/-/gulp-changed-0.0.39.tgz", - "integrity": "sha512-iW/0E8aQAZIVD6OAK2azY/5JCH77y2OPIjnNrjfQHmE6k05+51ABfsPospkZm+3S0jHrKuJ7ucImRLvKaR61Hg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/vinyl": "*" - } - }, - "node_modules/@types/gulp-minify": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@types/gulp-minify/-/gulp-minify-3.1.5.tgz", - "integrity": "sha512-Dx6dQ/o+FcXJQ0XntPCu7hL5iYMFIudQTnc11Cx9ZoOGA6ycnllqlm6zRwiQpwVm6HrA/GLUwYdU2E2DwXGBAg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/gulp-sass": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/gulp-sass/-/gulp-sass-5.0.4.tgz", @@ -1813,18 +1789,6 @@ "node": ">=6" } }, - "node_modules/ansi-cyan": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", - "integrity": "sha512-eCjan3AVo/SxZ0/MyIYRtkpxIu/H3xZN7URr1vXVrISxeyz8fUFz0FJziamK4sS8I+t35y4rHg1b2PklyBe/7A==", - "dev": true, - "dependencies": { - "ansi-wrap": "0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1852,18 +1816,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-red": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", - "integrity": "sha512-ewaIr5y+9CUTGFwZfpECUbFlGcC0GCw1oqR9RI6h1gQCd9Aj2GxSckCnPsVJnmfMZbwFYE+leZGASgkWl06Jow==", - "dev": true, - "dependencies": { - "ansi-wrap": "0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -1965,15 +1917,6 @@ "node": ">=0.10.0" } }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", @@ -2416,9 +2359,9 @@ } }, "node_modules/better-sqlite3": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.1.1.tgz", - "integrity": "sha512-bAlQQb7gwCgxNpDYafK0O4AaIOiTwA7srfqRtBbw0Nsiq6P+qxEYGl3hLw+9C5jX2FVjKW7oxkSouxlJ+3VX8A==", + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.1.2.tgz", + "integrity": "sha512-gujtFwavWU4MSPT+h9B+4pkvZdyOUkH54zgLdIrMmmmd4ZqiBIrRNBzNzYVFO417xo882uP5HBu4GjOfaSrIQw==", "hasInstallScript": true, "dependencies": { "bindings": "^1.5.0", @@ -2654,12 +2597,6 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, "node_modules/builtin-modules": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", @@ -2855,18 +2792,6 @@ "node": ">=8" } }, - "node_modules/change-file-extension": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/change-file-extension/-/change-file-extension-0.1.0.tgz", - "integrity": "sha512-k9K/7SnXkSuN5nwl+XyuFZfGmuw4w2V4e8xo4mT0tF5CtUjcFBlCbP2PLvpQQ3e/v7gp3Zeeeqb5neHDgNWswg==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/check-more-types": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", @@ -3039,15 +2964,6 @@ "node": ">=0.8" } }, - "node_modules/clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/clone-response": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", @@ -3065,17 +2981,6 @@ "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", "dev": true }, - "node_modules/cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, "node_modules/code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -3443,9 +3348,9 @@ "integrity": "sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg==" }, "node_modules/cypress": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.12.0.tgz", - "integrity": "sha512-udzS2JilmI9ApO/UuqurEwOvThclin5ntz7K0BtnHBs+tg2Bl9QShLISXpSEMDv/u8b6mqdoAdyKeZiSqKWL8g==", + "version": "13.13.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.13.0.tgz", + "integrity": "sha512-ou/MQUDq4tcDJI2FsPaod2FZpex4kpIK43JJlcBgWrX8WX7R/05ZxGTuxedOuZBfxjZxja+fbijZGyxiLP6CFA==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -3488,7 +3393,7 @@ "request-progress": "^3.0.0", "semver": "^7.5.3", "supports-color": "^8.1.1", - "tmp": "~0.2.1", + "tmp": "~0.2.3", "untildify": "^4.0.0", "yauzl": "^2.10.0" }, @@ -3787,12 +3692,6 @@ "node": ">=6.0.0" } }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, "node_modules/each-props": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz", @@ -3806,18 +3705,6 @@ "node": ">= 10.13.0" } }, - "node_modules/easy-transform-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/easy-transform-stream/-/easy-transform-stream-1.0.1.tgz", - "integrity": "sha512-ktkaa6XR7COAR3oj02CF3IOgz2m1hCaY3SfzvKT4Svt2MhHw9XCt+ncJNWfe2TGz31iqzNGZ8spdKQflj+Rlog==", - "dev": true, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -4749,21 +4636,6 @@ "node": ">= 0.6" } }, - "node_modules/event-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-4.0.1.tgz", - "integrity": "sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==", - "dev": true, - "dependencies": { - "duplexer": "^0.1.1", - "from": "^0.1.7", - "map-stream": "0.0.7", - "pause-stream": "^0.0.11", - "split": "^1.0.1", - "stream-combiner": "^0.2.2", - "through": "^2.3.8" - } - }, "node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -5401,12 +5273,6 @@ "node": ">= 0.6" } }, - "node_modules/from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==", - "dev": true - }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -5963,31 +5829,6 @@ "node": ">=10.13.0" } }, - "node_modules/gulp-changed": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/gulp-changed/-/gulp-changed-5.0.2.tgz", - "integrity": "sha512-mzuWzg3EQMpIYyNJoYQo5lAfCd4ibaGvyXiCRnpWxjHsgO3pmZl+mX/GM60ErhomLnwiBBfgdP4FAAM52heusA==", - "dev": true, - "dependencies": { - "change-file-extension": "^0.1.0", - "gulp-plugin-extras": "^0.3.0", - "touch": "^3.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - }, - "peerDependencies": { - "gulp": ">=4" - }, - "peerDependenciesMeta": { - "gulp": { - "optional": true - } - } - }, "node_modules/gulp-cli": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz", @@ -6014,164 +5855,6 @@ "node": ">=10.13.0" } }, - "node_modules/gulp-include": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/gulp-include/-/gulp-include-2.4.1.tgz", - "integrity": "sha512-ARF7H6CD/CCavOcvlLhs6sAY+turxI72Gwp+5X/sMNUha8eJXFloDaZ93nnSKIh0K8VR7b7PURHdXrIhFhQ9gg==", - "dev": true, - "dependencies": { - "ansi-colors": "^3.2.4", - "event-stream": "^4.0.1", - "glob": "^7.1.3", - "plugin-error": "^1.0.1", - "source-map": "^0.7.3", - "strip-bom": "^2.0.0", - "vinyl": "^2.2.0", - "vinyl-sourcemaps-apply": "^0.2.1" - } - }, - "node_modules/gulp-include/node_modules/ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/gulp-minify": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/gulp-minify/-/gulp-minify-3.1.0.tgz", - "integrity": "sha512-ixF41aYg+NQikI8hpoHdEclYcQkbGdXQu1CBdHaU7Epg8H6e8d2jWXw1+rBPgYwl/XpKgjHj7NI6gkhoSNSSAg==", - "dev": true, - "dependencies": { - "ansi-colors": "^1.0.1", - "minimatch": "^3.0.2", - "plugin-error": "^0.1.2", - "terser": "^3.7.6", - "through2": "^2.0.3", - "vinyl": "^2.1.0" - } - }, - "node_modules/gulp-minify/node_modules/ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "dependencies": { - "ansi-wrap": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-minify/node_modules/arr-diff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", - "integrity": "sha512-OQwDZUqYaQwyyhDJHThmzId8daf4/RFNLaeh3AevmSeZ5Y7ug4Ga/yKc6l6kTZOBW781rCj103ZuTh8GAsB3+Q==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.0.1", - "array-slice": "^0.2.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-minify/node_modules/arr-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", - "integrity": "sha512-t5db90jq+qdgk8aFnxEkjqta0B/GHrM1pxzuuZz2zWsOXc5nKu3t+76s/PQBA8FTcM/ipspIH9jWG4OxCBc2eA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-minify/node_modules/array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha512-rlVfZW/1Ph2SNySXwR9QYkChp8EkOEiTMO5Vwx60usw04i4nWemkm9RXmQqgkQFaLHsqLuADvjp6IfgL9l2M8Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-minify/node_modules/extend-shallow": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", - "integrity": "sha512-L7AGmkO6jhDkEBBGWlLtftA80Xq8DipnrRPr0pyi7GQLXkaq9JYA4xF4z6qnadIC6euiTDKco0cGSU9muw+WTw==", - "dev": true, - "dependencies": { - "kind-of": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-minify/node_modules/kind-of": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha512-aUH6ElPnMGon2/YkxRIigV32MOpTVcoXQ1Oo8aYn40s+sJ3j+0gFZsT8HKDcxNy7Fi9zuquWtGaGAahOdv5p/g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-minify/node_modules/plugin-error": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", - "integrity": "sha512-WzZHcm4+GO34sjFMxQMqZbsz3xiNEgonCskQ9v+IroMmYgk/tas8dG+Hr2D6IbRPybZ12oWpzE/w3cGJ6FJzOw==", - "dev": true, - "dependencies": { - "ansi-cyan": "^0.1.1", - "ansi-red": "^0.1.1", - "arr-diff": "^1.0.1", - "arr-union": "^2.0.1", - "extend-shallow": "^1.1.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gulp-minify/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/gulp-plugin-extras": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/gulp-plugin-extras/-/gulp-plugin-extras-0.3.0.tgz", - "integrity": "sha512-I/kOBSpo61QsGQZcqozZYEnDseKvpudUafVVWDLYgBFAUJ37kW5R8Sjw9cMYzpGyPUfEYOeoY4p+dkfLqgyJUQ==", - "dev": true, - "dependencies": { - "@types/vinyl": "^2.0.9", - "chalk": "^5.3.0", - "easy-transform-stream": "^1.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gulp-plugin-extras/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/gulp-sass": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-5.1.0.tgz", @@ -7014,12 +6697,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", - "dev": true - }, "node_modules/is-valid-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", @@ -7629,12 +7306,6 @@ "node": ">=0.10.0" } }, - "node_modules/map-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", - "integrity": "sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==", - "dev": true - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -8539,15 +8210,6 @@ "node": ">=8" } }, - "node_modules/pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==", - "dev": true, - "dependencies": { - "through": "~2.3" - } - }, "node_modules/pe-coff": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/pe-coff/-/pe-coff-1.0.0.tgz", @@ -9370,15 +9032,6 @@ "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", "dev": true }, - "node_modules/replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/replace-homedir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz", @@ -9998,15 +9651,6 @@ "node": ">= 14" } }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -10016,25 +9660,6 @@ "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sparkles": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz", @@ -10081,18 +9706,6 @@ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==" }, - "node_modules/split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, "node_modules/sprintf-js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", @@ -10148,16 +9761,6 @@ "node": ">= 0.10.0" } }, - "node_modules/stream-combiner": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", - "integrity": "sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==", - "dev": true, - "dependencies": { - "duplexer": "~0.1.1", - "through": "~2.3.4" - } - }, "node_modules/stream-composer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz", @@ -10264,18 +9867,6 @@ "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", - "dev": true, - "dependencies": { - "is-utf8": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -10523,38 +10114,6 @@ "streamx": "^2.12.5" } }, - "node_modules/terser": { - "version": "3.17.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", - "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", - "dev": true, - "dependencies": { - "commander": "^2.19.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.10" - }, - "bin": { - "terser": "bin/uglifyjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "node_modules/terser/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/text-decoder": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz", @@ -10580,15 +10139,12 @@ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, "engines": { - "node": ">=8.17.0" + "node": ">=14.14" } }, "node_modules/to-regex-range": { @@ -11145,23 +10701,6 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, - "node_modules/vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "dependencies": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/vinyl-contents": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz", @@ -11543,15 +11082,6 @@ "node": ">=8.0" } }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 77c5301a..36d49b61 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "@fortawesome/fontawesome-free": "^5.15.4", "activedirectory2": "^2.2.0", "better-sqlite-pool": "^0.3.2", - "better-sqlite3": "^11.1.1", + "better-sqlite3": "^11.1.2", "bulma-calendar": "^6.1.19", "camelcase": "^8.0.0", "compression": "^1.7.4", @@ -77,7 +77,7 @@ "@cityssm/mssql-multi-pool": "^3.1.5", "@cityssm/simple-fa5-checkbox": "^0.2.1", "@types/activedirectory2": "^1.2.6", - "@types/better-sqlite3": "^7.6.10", + "@types/better-sqlite3": "^7.6.11", "@types/compression": "^1.7.5", "@types/cookie-parser": "^1.4.7", "@types/csurf": "^1.11.5", @@ -86,8 +86,6 @@ "@types/express": "^4.17.21", "@types/express-session": "^1.18.0", "@types/gulp": "^4.0.17", - "@types/gulp-changed": "^0.0.39", - "@types/gulp-minify": "^3.1.5", "@types/gulp-sass": "^5.0.4", "@types/http-errors": "^2.0.4", "@types/leaflet": "^1.9.12", @@ -105,12 +103,9 @@ "bulma-steps": "^2.2.1", "bulma-switch": "^2.0.4", "bulma-tooltip": "^3.0.2", - "cypress": "^13.12.0", + "cypress": "^13.13.0", "cypress-axe": "^1.5.0", "gulp": "^5.0.0", - "gulp-changed": "^5.0.2", - "gulp-include": "^2.4.1", - "gulp-minify": "^3.1.0", "gulp-sass": "^5.1.0", "nodemon": "^3.1.4", "prettier-config-cityssm": "^1.0.0", diff --git a/public-typescript/adminTables.js b/public-typescript/adminTables.js deleted file mode 100644 index 0684145a..00000000 --- a/public-typescript/adminTables.js +++ /dev/null @@ -1,726 +0,0 @@ -"use strict"; -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -(() => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const los = exports.los; - // eslint-disable-next-line @typescript-eslint/no-unused-vars - function refreshFontAwesomeIcon(changeEvent) { - const inputElement = changeEvent.currentTarget; - const fontAwesomeIconClass = inputElement.value; - (inputElement.closest('.field')?.querySelectorAll('.button.is-static' - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - ))[1].innerHTML = - ``; - } - "use strict"; - // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair - /* eslint-disable unicorn/prefer-module */ - Object.defineProperty(exports, "__esModule", { value: true }); - let workOrderTypes = exports.workOrderTypes; - delete exports.workOrderTypes; - function updateWorkOrderType(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateWorkOrderType`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes; - bulmaJS.alert({ - message: 'Work Order Type Updated Successfully', - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: 'Error Updating Work Order Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function deleteWorkOrderType(clickEvent) { - const tableRowElement = clickEvent.currentTarget.closest('tr'); - const workOrderTypeId = tableRowElement.dataset.workOrderTypeId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteWorkOrderType`, { - workOrderTypeId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes; - if (workOrderTypes.length === 0) { - renderWorkOrderTypes(); - } - else { - tableRowElement.remove(); - } - bulmaJS.alert({ - message: 'Work Order Type Deleted Successfully', - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Work Order Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: 'Delete Work Order Type', - message: `Are you sure you want to delete this work order type?
- Note that no work orders will be removed.`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Work Order Type', - callbackFunction: doDelete - } - }); - } - function moveWorkOrderType(clickEvent) { - const buttonElement = clickEvent.currentTarget; - const tableRowElement = buttonElement.closest('tr'); - const workOrderTypeId = tableRowElement.dataset.workOrderTypeId; - cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' - ? 'doMoveWorkOrderTypeUp' - : 'doMoveWorkOrderTypeDown'}`, { - workOrderTypeId, - moveToEnd: clickEvent.shiftKey ? '1' : '0' - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes; - renderWorkOrderTypes(); - } - else { - bulmaJS.alert({ - title: 'Error Moving Work Order Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function renderWorkOrderTypes() { - const containerElement = document.querySelector('#container--workOrderTypes'); - if (workOrderTypes.length === 0) { - containerElement.innerHTML = ` -

There are no active work order types.

- `; - return; - } - containerElement.innerHTML = ''; - for (const workOrderType of workOrderTypes) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.workOrderTypeId = - workOrderType.workOrderTypeId.toString(); - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` -
- -
-
- -
-
- -
-
-
- -
-
- ${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderTypeUp', 'button--moveWorkOrderTypeDown', false)} -
-
- -
-
- `; - tableRowElement - .querySelector('form') - ?.addEventListener('submit', updateWorkOrderType); - tableRowElement.querySelector('.button--moveWorkOrderTypeUp').addEventListener('click', moveWorkOrderType); - tableRowElement.querySelector('.button--moveWorkOrderTypeDown').addEventListener('click', moveWorkOrderType); - tableRowElement - .querySelector('.button--deleteWorkOrderType') - ?.addEventListener('click', deleteWorkOrderType); - containerElement.append(tableRowElement); - } - } - ; - document.querySelector('#form--addWorkOrderType').addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault(); - const formElement = submitEvent.currentTarget; - cityssm.postJSON(`${los.urlPrefix}/admin/doAddWorkOrderType`, formElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes; - renderWorkOrderTypes(); - formElement.reset(); - formElement.querySelector('input')?.focus(); - } - else { - bulmaJS.alert({ - title: 'Error Adding Work Order Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - }); - renderWorkOrderTypes(); - - // eslint-disable-next-line no-secrets/no-secrets - "use strict"; - // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair - /* eslint-disable unicorn/prefer-module */ - Object.defineProperty(exports, "__esModule", { value: true }); - let workOrderMilestoneTypes = exports.workOrderMilestoneTypes; - delete exports.workOrderMilestoneTypes; - function updateWorkOrderMilestoneType(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateWorkOrderMilestoneType`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes; - bulmaJS.alert({ - message: 'Work Order Milestone Type Updated Successfully', - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: 'Error Updating Work Order Milestone Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function deleteWorkOrderMilestoneType(clickEvent) { - const tableRowElement = clickEvent.currentTarget.closest('tr'); - const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteWorkOrderMilestoneType`, { - workOrderMilestoneTypeId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes; - if (workOrderMilestoneTypes.length === 0) { - renderWorkOrderMilestoneTypes(); - } - else { - tableRowElement.remove(); - } - bulmaJS.alert({ - message: 'Work Order Milestone Type Deleted Successfully', - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Work Order Milestone Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: 'Delete Work Order Milestone Type', - message: `Are you sure you want to delete this work order milestone type?
- Note that no work orders will be removed.`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Work Order Milestone Type', - callbackFunction: doDelete - } - }); - } - function moveWorkOrderMilestoneType(clickEvent) { - const buttonElement = clickEvent.currentTarget; - const tableRowElement = buttonElement.closest('tr'); - const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId; - cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' - ? 'doMoveWorkOrderMilestoneTypeUp' - : 'doMoveWorkOrderMilestoneTypeDown'}`, { - workOrderMilestoneTypeId, - moveToEnd: clickEvent.shiftKey ? '1' : '0' - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes; - renderWorkOrderMilestoneTypes(); - } - else { - bulmaJS.alert({ - title: 'Error Moving Work Order Milestone Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function renderWorkOrderMilestoneTypes() { - const containerElement = document.querySelector('#container--workOrderMilestoneTypes'); - if (workOrderMilestoneTypes.length === 0) { - containerElement.innerHTML = ` -

There are no active work order milestone types.

- `; - return; - } - containerElement.innerHTML = ''; - for (const workOrderMilestoneType of workOrderMilestoneTypes) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.workOrderMilestoneTypeId = - workOrderMilestoneType.workOrderMilestoneTypeId.toString(); - // eslint-disable-next-line no-unsanitized/property, no-secrets/no-secrets - tableRowElement.innerHTML = ` -
- -
-
- -
-
- -
-
-
- -
-
- ${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderMilestoneTypeUp', 'button--moveWorkOrderMilestoneTypeDown', false)} -
-
- -
-
- `; - tableRowElement - .querySelector('form') - ?.addEventListener('submit', updateWorkOrderMilestoneType); - tableRowElement.querySelector('.button--moveWorkOrderMilestoneTypeUp').addEventListener('click', moveWorkOrderMilestoneType); - tableRowElement.querySelector('.button--moveWorkOrderMilestoneTypeDown').addEventListener('click', moveWorkOrderMilestoneType); - tableRowElement - .querySelector('.button--deleteWorkOrderMilestoneType') - ?.addEventListener('click', deleteWorkOrderMilestoneType); - containerElement.append(tableRowElement); - } - } - ; - document.querySelector('#form--addWorkOrderMilestoneType').addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault(); - const formElement = submitEvent.currentTarget; - cityssm.postJSON(`${los.urlPrefix}/admin/doAddWorkOrderMilestoneType`, formElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes; - renderWorkOrderMilestoneTypes(); - formElement.reset(); - formElement.querySelector('input')?.focus(); - } - else { - bulmaJS.alert({ - title: 'Error Adding Work Order Milestone Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - }); - renderWorkOrderMilestoneTypes(); - - "use strict"; - // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair - /* eslint-disable unicorn/prefer-module */ - Object.defineProperty(exports, "__esModule", { value: true }); - let lotStatuses = exports.lotStatuses; - delete exports.lotStatuses; - function updateLotStatus(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateLotStatus`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses; - bulmaJS.alert({ - message: `${los.escapedAliases.Lot} Status Updated Successfully`, - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: `Error Updating ${los.escapedAliases.Lot} Status`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function deleteLotStatus(clickEvent) { - const tableRowElement = clickEvent.currentTarget.closest('tr'); - const lotStatusId = tableRowElement.dataset.lotStatusId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteLotStatus`, { - lotStatusId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses; - if (lotStatuses.length === 0) { - renderLotStatuses(); - } - else { - tableRowElement.remove(); - } - bulmaJS.alert({ - message: `${los.escapedAliases.Lot} Status Deleted Successfully`, - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: `Error Deleting ${los.escapedAliases.Lot} Status`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Lot} Status`, - message: `Are you sure you want to delete this status?
- Note that no ${los.escapedAliases.lot} will be removed.`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Status', - callbackFunction: doDelete - } - }); - } - function moveLotStatus(clickEvent) { - const buttonElement = clickEvent.currentTarget; - const tableRowElement = buttonElement.closest('tr'); - const lotStatusId = tableRowElement.dataset.lotStatusId; - cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' - ? 'doMoveLotStatusUp' - : 'doMoveLotStatusDown'}`, { - lotStatusId, - moveToEnd: clickEvent.shiftKey ? '1' : '0' - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses; - renderLotStatuses(); - } - else { - bulmaJS.alert({ - title: `Error Moving ${los.escapedAliases.Lot} Status`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function renderLotStatuses() { - const containerElement = document.querySelector('#container--lotStatuses'); - if (lotStatuses.length === 0) { - // eslint-disable-next-line no-unsanitized/property - containerElement.innerHTML = ` -

There are no active ${los.escapedAliases.lot} statuses.

- `; - return; - } - containerElement.innerHTML = ''; - for (const lotStatus of lotStatuses) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.lotStatusId = lotStatus.lotStatusId.toString(); - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` -
- -
-
- -
-
- -
-
-
- -
-
- ${los.getMoveUpDownButtonFieldHTML('button--moveLotStatusUp', 'button--moveLotStatusDown', false)} -
-
- -
-
- `; - tableRowElement - .querySelector('form') - ?.addEventListener('submit', updateLotStatus); - tableRowElement.querySelector('.button--moveLotStatusUp').addEventListener('click', moveLotStatus); - tableRowElement.querySelector('.button--moveLotStatusDown').addEventListener('click', moveLotStatus); - tableRowElement - .querySelector('.button--deleteLotStatus') - ?.addEventListener('click', deleteLotStatus); - containerElement.append(tableRowElement); - } - } - ; - document.querySelector('#form--addLotStatus').addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault(); - const formElement = submitEvent.currentTarget; - cityssm.postJSON(`${los.urlPrefix}/admin/doAddLotStatus`, formElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses; - renderLotStatuses(); - formElement.reset(); - formElement.querySelector('input')?.focus(); - } - else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Lot} Status`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - }); - renderLotStatuses(); - - // eslint-disable-next-line no-secrets/no-secrets - "use strict"; - // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair - /* eslint-disable unicorn/prefer-module */ - Object.defineProperty(exports, "__esModule", { value: true }); - let lotOccupantTypes = exports.lotOccupantTypes; - delete exports.lotOccupantTypes; - function updateLotOccupantType(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateLotOccupantType`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupantTypes = responseJSON.lotOccupantTypes; - bulmaJS.alert({ - message: `${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type Updated Successfully`, - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: `Error Updating ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function deleteLotOccupantType(clickEvent) { - const tableRowElement = clickEvent.currentTarget.closest('tr'); - const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteLotOccupantType`, { - lotOccupantTypeId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupantTypes = responseJSON.lotOccupantTypes; - if (lotOccupantTypes.length === 0) { - renderLotOccupantTypes(); - } - else { - tableRowElement.remove(); - } - bulmaJS.alert({ - message: `${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type Deleted Successfully`, - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: `Error Deleting ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: `Are you sure you want to delete this ${los.escapedAliases.lot} ${los.escapedAliases.occupant} type?
- Note that no ${los.escapedAliases.lot} ${los.escapedAliases.occupants} will be removed.`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: `Yes, Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - callbackFunction: doDelete - } - }); - } - function moveLotOccupantType(clickEvent) { - const buttonElement = clickEvent.currentTarget; - const tableRowElement = buttonElement.closest('tr'); - const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId; - cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' - ? 'doMoveLotOccupantTypeUp' - : 'doMoveLotOccupantTypeDown'}`, { - lotOccupantTypeId, - moveToEnd: clickEvent.shiftKey ? '1' : '0' - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupantTypes = responseJSON.lotOccupantTypes; - renderLotOccupantTypes(); - } - else { - bulmaJS.alert({ - title: `Error Moving ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function renderLotOccupantTypes() { - const containerElement = document.querySelector('#container--lotOccupantTypes'); - if (lotOccupantTypes.length === 0) { - // eslint-disable-next-line no-unsanitized/property - containerElement.innerHTML = ` -
-

There are no active ${los.escapedAliases.lot} ${los.escapedAliases.occupant} types.

-
- `; - return; - } - containerElement.innerHTML = ''; - for (const lotOccupantType of lotOccupantTypes) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.lotOccupantTypeId = - lotOccupantType.lotOccupantTypeId.toString(); - const formId = `form--lotOccupantType-${lotOccupantType.lotOccupantTypeId.toString()}`; - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` -
-
- -
-
- -
-
- fa- -
-
- -
-
- - - -
-
- -
-
- -
-
- -
- - -
- -
-
- ${los.getMoveUpDownButtonFieldHTML('button--moveLotOccupantTypeUp', 'button--moveLotOccupantTypeDown', false)} -
-
- -
-
- `; - const fontAwesomeInputElement = tableRowElement.querySelector("input[name='fontAwesomeIconClass']"); - fontAwesomeInputElement.addEventListener('keyup', refreshFontAwesomeIcon); - fontAwesomeInputElement.addEventListener('change', refreshFontAwesomeIcon); - tableRowElement - .querySelector('form') - ?.addEventListener('submit', updateLotOccupantType); - tableRowElement.querySelector('.button--moveLotOccupantTypeUp').addEventListener('click', moveLotOccupantType); - tableRowElement.querySelector('.button--moveLotOccupantTypeDown').addEventListener('click', moveLotOccupantType); - tableRowElement - .querySelector('.button--deleteLotOccupantType') - ?.addEventListener('click', deleteLotOccupantType); - containerElement.append(tableRowElement); - } - } - ; - document.querySelector('#form--addLotOccupantType').addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault(); - const formElement = submitEvent.currentTarget; - cityssm.postJSON(`${los.urlPrefix}/admin/doAddLotOccupantType`, formElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupantTypes = responseJSON.lotOccupantTypes; - renderLotOccupantTypes(); - formElement.reset(); - formElement.querySelector('input')?.focus(); - } - else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - }); - renderLotOccupantTypes(); - -})(); diff --git a/public-typescript/adminTables/adminTables.js b/public-typescript/adminTables/adminTables.js deleted file mode 100644 index 6e07ab9b..00000000 --- a/public-typescript/adminTables/adminTables.js +++ /dev/null @@ -1,23 +0,0 @@ -"use strict"; -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -(() => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const los = exports.los; - // eslint-disable-next-line @typescript-eslint/no-unused-vars - function refreshFontAwesomeIcon(changeEvent) { - const inputElement = changeEvent.currentTarget; - const fontAwesomeIconClass = inputElement.value; - (inputElement.closest('.field')?.querySelectorAll('.button.is-static' - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - ))[1].innerHTML = - ``; - } - //=include adminTablesWorkOrderTypes.js - // eslint-disable-next-line no-secrets/no-secrets - //=include adminTablesWorkOrderMilestoneTypes.js - //=include adminTablesLotStatuses.js - // eslint-disable-next-line no-secrets/no-secrets - //=include adminTablesLotOccupantTypes.js -})(); diff --git a/public-typescript/adminTables/adminTables.ts b/public-typescript/adminTables/adminTables.ts deleted file mode 100644 index 5ced86d9..00000000 --- a/public-typescript/adminTables/adminTables.ts +++ /dev/null @@ -1,36 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ - -import type { LOS } from '../../types/globalTypes.js' - -declare const exports: Record -;(() => { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const los = exports.los as LOS - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - function refreshFontAwesomeIcon(changeEvent: Event): void { - const inputElement = changeEvent.currentTarget as HTMLInputElement - - const fontAwesomeIconClass = inputElement.value - - // eslint-disable-next-line no-unsanitized/property - ;( - inputElement.closest('.field')?.querySelectorAll( - '.button.is-static' - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - ) as NodeListOf - )[1].innerHTML = - `` - } - - //=include adminTablesWorkOrderTypes.js - - // eslint-disable-next-line no-secrets/no-secrets - //=include adminTablesWorkOrderMilestoneTypes.js - - //=include adminTablesLotStatuses.js - - // eslint-disable-next-line no-secrets/no-secrets - //=include adminTablesLotOccupantTypes.js -})() diff --git a/public-typescript/adminTables/adminTablesLotOccupantTypes.d.ts b/public-typescript/adminTables/adminTablesLotOccupantTypes.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/public-typescript/adminTables/adminTablesLotOccupantTypes.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/public-typescript/adminTables/adminTablesLotOccupantTypes.js b/public-typescript/adminTables/adminTablesLotOccupantTypes.js deleted file mode 100644 index c3ae7fc1..00000000 --- a/public-typescript/adminTables/adminTablesLotOccupantTypes.js +++ /dev/null @@ -1,204 +0,0 @@ -"use strict"; -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -let lotOccupantTypes = exports.lotOccupantTypes; -delete exports.lotOccupantTypes; -function updateLotOccupantType(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateLotOccupantType`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupantTypes = responseJSON.lotOccupantTypes; - bulmaJS.alert({ - message: `${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type Updated Successfully`, - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: `Error Updating ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); -} -function deleteLotOccupantType(clickEvent) { - const tableRowElement = clickEvent.currentTarget.closest('tr'); - const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteLotOccupantType`, { - lotOccupantTypeId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupantTypes = responseJSON.lotOccupantTypes; - if (lotOccupantTypes.length === 0) { - renderLotOccupantTypes(); - } - else { - tableRowElement.remove(); - } - bulmaJS.alert({ - message: `${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type Deleted Successfully`, - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: `Error Deleting ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: `Are you sure you want to delete this ${los.escapedAliases.lot} ${los.escapedAliases.occupant} type?
- Note that no ${los.escapedAliases.lot} ${los.escapedAliases.occupants} will be removed.`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: `Yes, Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - callbackFunction: doDelete - } - }); -} -function moveLotOccupantType(clickEvent) { - const buttonElement = clickEvent.currentTarget; - const tableRowElement = buttonElement.closest('tr'); - const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId; - cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' - ? 'doMoveLotOccupantTypeUp' - : 'doMoveLotOccupantTypeDown'}`, { - lotOccupantTypeId, - moveToEnd: clickEvent.shiftKey ? '1' : '0' - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupantTypes = responseJSON.lotOccupantTypes; - renderLotOccupantTypes(); - } - else { - bulmaJS.alert({ - title: `Error Moving ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); -} -function renderLotOccupantTypes() { - const containerElement = document.querySelector('#container--lotOccupantTypes'); - if (lotOccupantTypes.length === 0) { - // eslint-disable-next-line no-unsanitized/property - containerElement.innerHTML = ` -
-

There are no active ${los.escapedAliases.lot} ${los.escapedAliases.occupant} types.

-
- `; - return; - } - containerElement.innerHTML = ''; - for (const lotOccupantType of lotOccupantTypes) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.lotOccupantTypeId = - lotOccupantType.lotOccupantTypeId.toString(); - const formId = `form--lotOccupantType-${lotOccupantType.lotOccupantTypeId.toString()}`; - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` -
-
- -
-
- -
-
- fa- -
-
- -
-
- - - -
-
- -
-
- -
-
- -
- - -
- -
-
- ${los.getMoveUpDownButtonFieldHTML('button--moveLotOccupantTypeUp', 'button--moveLotOccupantTypeDown', false)} -
-
- -
-
- `; - const fontAwesomeInputElement = tableRowElement.querySelector("input[name='fontAwesomeIconClass']"); - fontAwesomeInputElement.addEventListener('keyup', refreshFontAwesomeIcon); - fontAwesomeInputElement.addEventListener('change', refreshFontAwesomeIcon); - tableRowElement - .querySelector('form') - ?.addEventListener('submit', updateLotOccupantType); - tableRowElement.querySelector('.button--moveLotOccupantTypeUp').addEventListener('click', moveLotOccupantType); - tableRowElement.querySelector('.button--moveLotOccupantTypeDown').addEventListener('click', moveLotOccupantType); - tableRowElement - .querySelector('.button--deleteLotOccupantType') - ?.addEventListener('click', deleteLotOccupantType); - containerElement.append(tableRowElement); - } -} -; -document.querySelector('#form--addLotOccupantType').addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault(); - const formElement = submitEvent.currentTarget; - cityssm.postJSON(`${los.urlPrefix}/admin/doAddLotOccupantType`, formElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupantTypes = responseJSON.lotOccupantTypes; - renderLotOccupantTypes(); - formElement.reset(); - formElement.querySelector('input')?.focus(); - } - else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); -}); -renderLotOccupantTypes(); diff --git a/public-typescript/adminTables/adminTablesLotOccupantTypes.ts b/public-typescript/adminTables/adminTablesLotOccupantTypes.ts deleted file mode 100644 index 30d02c8f..00000000 --- a/public-typescript/adminTables/adminTablesLotOccupantTypes.ts +++ /dev/null @@ -1,292 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ - -import type { BulmaJS } from '@cityssm/bulma-js/types.js' -import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' - -import type { LOS } from '../../types/globalTypes.js' -import type { LotOccupantType } from '../../types/recordTypes.js' - -declare const cityssm: cityssmGlobal -declare const bulmaJS: BulmaJS - -declare const los: LOS -declare const exports: Record - -declare const refreshFontAwesomeIcon: (changeEvent: Event) => void - -let lotOccupantTypes = exports.lotOccupantTypes as LotOccupantType[] -delete exports.lotOccupantTypes - -type ResponseJSON = - | { - success: true - lotOccupantTypes: LotOccupantType[] - } - | { - success: false - errorMessage: string - } - -function updateLotOccupantType(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/admin/doUpdateLotOccupantType`, - submitEvent.currentTarget, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - lotOccupantTypes = responseJSON.lotOccupantTypes - - bulmaJS.alert({ - message: `${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type Updated Successfully`, - contextualColorName: 'success' - }) - } else { - bulmaJS.alert({ - title: `Error Updating ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) -} - -function deleteLotOccupantType(clickEvent: Event): void { - const tableRowElement = (clickEvent.currentTarget as HTMLElement).closest( - 'tr' - ) as HTMLTableRowElement - - const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/admin/doDeleteLotOccupantType`, - { - lotOccupantTypeId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - lotOccupantTypes = responseJSON.lotOccupantTypes - - if (lotOccupantTypes.length === 0) { - renderLotOccupantTypes() - } else { - tableRowElement.remove() - } - - bulmaJS.alert({ - message: `${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type Deleted Successfully`, - contextualColorName: 'success' - }) - } else { - bulmaJS.alert({ - title: `Error Deleting ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: `Are you sure you want to delete this ${los.escapedAliases.lot} ${los.escapedAliases.occupant} type?
- Note that no ${los.escapedAliases.lot} ${los.escapedAliases.occupants} will be removed.`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: `Yes, Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - callbackFunction: doDelete - } - }) -} - -function moveLotOccupantType(clickEvent: MouseEvent): void { - const buttonElement = clickEvent.currentTarget as HTMLButtonElement - - const tableRowElement = buttonElement.closest('tr') as HTMLTableRowElement - - const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId - - cityssm.postJSON( - `${los.urlPrefix}/admin/${ - buttonElement.dataset.direction === 'up' - ? 'doMoveLotOccupantTypeUp' - : 'doMoveLotOccupantTypeDown' - }`, - { - lotOccupantTypeId, - moveToEnd: clickEvent.shiftKey ? '1' : '0' - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - lotOccupantTypes = responseJSON.lotOccupantTypes - renderLotOccupantTypes() - } else { - bulmaJS.alert({ - title: `Error Moving ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) -} - -function renderLotOccupantTypes(): void { - const containerElement = document.querySelector( - '#container--lotOccupantTypes' - ) as HTMLTableSectionElement - - if (lotOccupantTypes.length === 0) { - // eslint-disable-next-line no-unsanitized/property - containerElement.innerHTML = ` -
-

There are no active ${los.escapedAliases.lot} ${los.escapedAliases.occupant} types.

-
- ` - - return - } - - containerElement.innerHTML = '' - - for (const lotOccupantType of lotOccupantTypes) { - const tableRowElement = document.createElement('tr') - - tableRowElement.dataset.lotOccupantTypeId = - lotOccupantType.lotOccupantTypeId.toString() - - const formId = `form--lotOccupantType-${lotOccupantType.lotOccupantTypeId.toString()}` - - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` -
-
- -
-
- -
-
- fa- -
-
- -
-
- - - -
-
- -
-
- -
-
- -
- - -
- -
-
- ${los.getMoveUpDownButtonFieldHTML( - 'button--moveLotOccupantTypeUp', - 'button--moveLotOccupantTypeDown', - false - )} -
-
- -
-
- ` - - const fontAwesomeInputElement = tableRowElement.querySelector( - "input[name='fontAwesomeIconClass']" - ) as HTMLInputElement - - fontAwesomeInputElement.addEventListener('keyup', refreshFontAwesomeIcon) - fontAwesomeInputElement.addEventListener('change', refreshFontAwesomeIcon) - - tableRowElement - .querySelector('form') - ?.addEventListener('submit', updateLotOccupantType) - ;( - tableRowElement.querySelector( - '.button--moveLotOccupantTypeUp' - ) as HTMLButtonElement - ).addEventListener('click', moveLotOccupantType) - ;( - tableRowElement.querySelector( - '.button--moveLotOccupantTypeDown' - ) as HTMLButtonElement - ).addEventListener('click', moveLotOccupantType) - - tableRowElement - .querySelector('.button--deleteLotOccupantType') - ?.addEventListener('click', deleteLotOccupantType) - - containerElement.append(tableRowElement) - } -} -;( - document.querySelector('#form--addLotOccupantType') as HTMLFormElement -).addEventListener('submit', (submitEvent: SubmitEvent) => { - submitEvent.preventDefault() - - const formElement = submitEvent.currentTarget as HTMLFormElement - - cityssm.postJSON( - `${los.urlPrefix}/admin/doAddLotOccupantType`, - formElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - lotOccupantTypes = responseJSON.lotOccupantTypes - renderLotOccupantTypes() - formElement.reset() - formElement.querySelector('input')?.focus() - } else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) -}) - -renderLotOccupantTypes() diff --git a/public-typescript/adminTables/adminTablesLotStatuses.d.ts b/public-typescript/adminTables/adminTablesLotStatuses.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/public-typescript/adminTables/adminTablesLotStatuses.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/public-typescript/adminTables/adminTablesLotStatuses.js b/public-typescript/adminTables/adminTablesLotStatuses.js deleted file mode 100644 index 3d70f73e..00000000 --- a/public-typescript/adminTables/adminTablesLotStatuses.js +++ /dev/null @@ -1,167 +0,0 @@ -"use strict"; -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -let lotStatuses = exports.lotStatuses; -delete exports.lotStatuses; -function updateLotStatus(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateLotStatus`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses; - bulmaJS.alert({ - message: `${los.escapedAliases.Lot} Status Updated Successfully`, - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: `Error Updating ${los.escapedAliases.Lot} Status`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); -} -function deleteLotStatus(clickEvent) { - const tableRowElement = clickEvent.currentTarget.closest('tr'); - const lotStatusId = tableRowElement.dataset.lotStatusId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteLotStatus`, { - lotStatusId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses; - if (lotStatuses.length === 0) { - renderLotStatuses(); - } - else { - tableRowElement.remove(); - } - bulmaJS.alert({ - message: `${los.escapedAliases.Lot} Status Deleted Successfully`, - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: `Error Deleting ${los.escapedAliases.Lot} Status`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Lot} Status`, - message: `Are you sure you want to delete this status?
- Note that no ${los.escapedAliases.lot} will be removed.`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Status', - callbackFunction: doDelete - } - }); -} -function moveLotStatus(clickEvent) { - const buttonElement = clickEvent.currentTarget; - const tableRowElement = buttonElement.closest('tr'); - const lotStatusId = tableRowElement.dataset.lotStatusId; - cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' - ? 'doMoveLotStatusUp' - : 'doMoveLotStatusDown'}`, { - lotStatusId, - moveToEnd: clickEvent.shiftKey ? '1' : '0' - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses; - renderLotStatuses(); - } - else { - bulmaJS.alert({ - title: `Error Moving ${los.escapedAliases.Lot} Status`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); -} -function renderLotStatuses() { - const containerElement = document.querySelector('#container--lotStatuses'); - if (lotStatuses.length === 0) { - // eslint-disable-next-line no-unsanitized/property - containerElement.innerHTML = ` -

There are no active ${los.escapedAliases.lot} statuses.

- `; - return; - } - containerElement.innerHTML = ''; - for (const lotStatus of lotStatuses) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.lotStatusId = lotStatus.lotStatusId.toString(); - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` -
- -
-
- -
-
- -
-
-
- -
-
- ${los.getMoveUpDownButtonFieldHTML('button--moveLotStatusUp', 'button--moveLotStatusDown', false)} -
-
- -
-
- `; - tableRowElement - .querySelector('form') - ?.addEventListener('submit', updateLotStatus); - tableRowElement.querySelector('.button--moveLotStatusUp').addEventListener('click', moveLotStatus); - tableRowElement.querySelector('.button--moveLotStatusDown').addEventListener('click', moveLotStatus); - tableRowElement - .querySelector('.button--deleteLotStatus') - ?.addEventListener('click', deleteLotStatus); - containerElement.append(tableRowElement); - } -} -; -document.querySelector('#form--addLotStatus').addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault(); - const formElement = submitEvent.currentTarget; - cityssm.postJSON(`${los.urlPrefix}/admin/doAddLotStatus`, formElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses; - renderLotStatuses(); - formElement.reset(); - formElement.querySelector('input')?.focus(); - } - else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Lot} Status`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); -}); -renderLotStatuses(); diff --git a/public-typescript/adminTables/adminTablesLotStatuses.ts b/public-typescript/adminTables/adminTablesLotStatuses.ts deleted file mode 100644 index 5dca8160..00000000 --- a/public-typescript/adminTables/adminTablesLotStatuses.ts +++ /dev/null @@ -1,248 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ - -import type { BulmaJS } from '@cityssm/bulma-js/types.js' -import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' - -import type { LOS } from '../../types/globalTypes.js' -import type { LotStatus } from '../../types/recordTypes.js' - -declare const cityssm: cityssmGlobal -declare const bulmaJS: BulmaJS - -declare const los: LOS -declare const exports: Record - -let lotStatuses = exports.lotStatuses as LotStatus[] -delete exports.lotStatuses - -type ResponseJSON = - | { - success: true - lotStatuses: LotStatus[] - } - | { - success: false - errorMessage: string - } - -function updateLotStatus(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/admin/doUpdateLotStatus`, - submitEvent.currentTarget, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses - - bulmaJS.alert({ - message: `${los.escapedAliases.Lot} Status Updated Successfully`, - contextualColorName: 'success' - }) - } else { - bulmaJS.alert({ - title: `Error Updating ${los.escapedAliases.Lot} Status`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) -} - -function deleteLotStatus(clickEvent: Event): void { - const tableRowElement = (clickEvent.currentTarget as HTMLElement).closest( - 'tr' - ) as HTMLTableRowElement - - const lotStatusId = tableRowElement.dataset.lotStatusId - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/admin/doDeleteLotStatus`, - { - lotStatusId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses - - if (lotStatuses.length === 0) { - renderLotStatuses() - } else { - tableRowElement.remove() - } - - bulmaJS.alert({ - message: `${los.escapedAliases.Lot} Status Deleted Successfully`, - contextualColorName: 'success' - }) - } else { - bulmaJS.alert({ - title: `Error Deleting ${los.escapedAliases.Lot} Status`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Lot} Status`, - message: `Are you sure you want to delete this status?
- Note that no ${los.escapedAliases.lot} will be removed.`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Status', - callbackFunction: doDelete - } - }) -} - -function moveLotStatus(clickEvent: MouseEvent): void { - const buttonElement = clickEvent.currentTarget as HTMLButtonElement - - const tableRowElement = buttonElement.closest('tr') as HTMLTableRowElement - - const lotStatusId = tableRowElement.dataset.lotStatusId - - cityssm.postJSON( - `${los.urlPrefix}/admin/${ - buttonElement.dataset.direction === 'up' - ? 'doMoveLotStatusUp' - : 'doMoveLotStatusDown' - }`, - { - lotStatusId, - moveToEnd: clickEvent.shiftKey ? '1' : '0' - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses - renderLotStatuses() - } else { - bulmaJS.alert({ - title: `Error Moving ${los.escapedAliases.Lot} Status`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) -} - -function renderLotStatuses(): void { - const containerElement = document.querySelector( - '#container--lotStatuses' - ) as HTMLTableSectionElement - - if (lotStatuses.length === 0) { - // eslint-disable-next-line no-unsanitized/property - containerElement.innerHTML = ` -

There are no active ${los.escapedAliases.lot} statuses.

- ` - - return - } - - containerElement.innerHTML = '' - - for (const lotStatus of lotStatuses) { - const tableRowElement = document.createElement('tr') - - tableRowElement.dataset.lotStatusId = lotStatus.lotStatusId.toString() - - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` -
- -
-
- -
-
- -
-
-
- -
-
- ${los.getMoveUpDownButtonFieldHTML( - 'button--moveLotStatusUp', - 'button--moveLotStatusDown', - false - )} -
-
- -
-
- ` - - tableRowElement - .querySelector('form') - ?.addEventListener('submit', updateLotStatus) - ;( - tableRowElement.querySelector( - '.button--moveLotStatusUp' - ) as HTMLButtonElement - ).addEventListener('click', moveLotStatus) - ;( - tableRowElement.querySelector( - '.button--moveLotStatusDown' - ) as HTMLButtonElement - ).addEventListener('click', moveLotStatus) - - tableRowElement - .querySelector('.button--deleteLotStatus') - ?.addEventListener('click', deleteLotStatus) - - containerElement.append(tableRowElement) - } -} -;( - document.querySelector('#form--addLotStatus') as HTMLFormElement -).addEventListener('submit', (submitEvent: SubmitEvent) => { - submitEvent.preventDefault() - - const formElement = submitEvent.currentTarget as HTMLFormElement - - cityssm.postJSON( - `${los.urlPrefix}/admin/doAddLotStatus`, - formElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - lotStatuses = responseJSON.lotStatuses - renderLotStatuses() - formElement.reset() - formElement.querySelector('input')?.focus() - } else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Lot} Status`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) -}) - -renderLotStatuses() diff --git a/public-typescript/adminTables/adminTablesWorkOrderMilestoneTypes.d.ts b/public-typescript/adminTables/adminTablesWorkOrderMilestoneTypes.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/public-typescript/adminTables/adminTablesWorkOrderMilestoneTypes.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/public-typescript/adminTables/adminTablesWorkOrderMilestoneTypes.js b/public-typescript/adminTables/adminTablesWorkOrderMilestoneTypes.js deleted file mode 100644 index 52637f78..00000000 --- a/public-typescript/adminTables/adminTablesWorkOrderMilestoneTypes.js +++ /dev/null @@ -1,166 +0,0 @@ -"use strict"; -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -let workOrderMilestoneTypes = exports.workOrderMilestoneTypes; -delete exports.workOrderMilestoneTypes; -function updateWorkOrderMilestoneType(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateWorkOrderMilestoneType`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes; - bulmaJS.alert({ - message: 'Work Order Milestone Type Updated Successfully', - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: 'Error Updating Work Order Milestone Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); -} -function deleteWorkOrderMilestoneType(clickEvent) { - const tableRowElement = clickEvent.currentTarget.closest('tr'); - const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteWorkOrderMilestoneType`, { - workOrderMilestoneTypeId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes; - if (workOrderMilestoneTypes.length === 0) { - renderWorkOrderMilestoneTypes(); - } - else { - tableRowElement.remove(); - } - bulmaJS.alert({ - message: 'Work Order Milestone Type Deleted Successfully', - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Work Order Milestone Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: 'Delete Work Order Milestone Type', - message: `Are you sure you want to delete this work order milestone type?
- Note that no work orders will be removed.`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Work Order Milestone Type', - callbackFunction: doDelete - } - }); -} -function moveWorkOrderMilestoneType(clickEvent) { - const buttonElement = clickEvent.currentTarget; - const tableRowElement = buttonElement.closest('tr'); - const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId; - cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' - ? 'doMoveWorkOrderMilestoneTypeUp' - : 'doMoveWorkOrderMilestoneTypeDown'}`, { - workOrderMilestoneTypeId, - moveToEnd: clickEvent.shiftKey ? '1' : '0' - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes; - renderWorkOrderMilestoneTypes(); - } - else { - bulmaJS.alert({ - title: 'Error Moving Work Order Milestone Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); -} -function renderWorkOrderMilestoneTypes() { - const containerElement = document.querySelector('#container--workOrderMilestoneTypes'); - if (workOrderMilestoneTypes.length === 0) { - containerElement.innerHTML = ` -

There are no active work order milestone types.

- `; - return; - } - containerElement.innerHTML = ''; - for (const workOrderMilestoneType of workOrderMilestoneTypes) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.workOrderMilestoneTypeId = - workOrderMilestoneType.workOrderMilestoneTypeId.toString(); - // eslint-disable-next-line no-unsanitized/property, no-secrets/no-secrets - tableRowElement.innerHTML = ` -
- -
-
- -
-
- -
-
-
- -
-
- ${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderMilestoneTypeUp', 'button--moveWorkOrderMilestoneTypeDown', false)} -
-
- -
-
- `; - tableRowElement - .querySelector('form') - ?.addEventListener('submit', updateWorkOrderMilestoneType); - tableRowElement.querySelector('.button--moveWorkOrderMilestoneTypeUp').addEventListener('click', moveWorkOrderMilestoneType); - tableRowElement.querySelector('.button--moveWorkOrderMilestoneTypeDown').addEventListener('click', moveWorkOrderMilestoneType); - tableRowElement - .querySelector('.button--deleteWorkOrderMilestoneType') - ?.addEventListener('click', deleteWorkOrderMilestoneType); - containerElement.append(tableRowElement); - } -} -; -document.querySelector('#form--addWorkOrderMilestoneType').addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault(); - const formElement = submitEvent.currentTarget; - cityssm.postJSON(`${los.urlPrefix}/admin/doAddWorkOrderMilestoneType`, formElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes; - renderWorkOrderMilestoneTypes(); - formElement.reset(); - formElement.querySelector('input')?.focus(); - } - else { - bulmaJS.alert({ - title: 'Error Adding Work Order Milestone Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); -}); -renderWorkOrderMilestoneTypes(); diff --git a/public-typescript/adminTables/adminTablesWorkOrderMilestoneTypes.ts b/public-typescript/adminTables/adminTablesWorkOrderMilestoneTypes.ts deleted file mode 100644 index 5acbf1aa..00000000 --- a/public-typescript/adminTables/adminTablesWorkOrderMilestoneTypes.ts +++ /dev/null @@ -1,250 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ - -import type { BulmaJS } from '@cityssm/bulma-js/types.js' -import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' - -import type { LOS } from '../../types/globalTypes.js' -import type { WorkOrderMilestoneType } from '../../types/recordTypes.js' - -declare const cityssm: cityssmGlobal -declare const bulmaJS: BulmaJS - -declare const los: LOS -declare const exports: Record - -let workOrderMilestoneTypes = - exports.workOrderMilestoneTypes as WorkOrderMilestoneType[] -delete exports.workOrderMilestoneTypes - -type ResponseJSON = - | { - success: true - workOrderMilestoneTypes: WorkOrderMilestoneType[] - } - | { - success: false - errorMessage: string - } - -function updateWorkOrderMilestoneType(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/admin/doUpdateWorkOrderMilestoneType`, - submitEvent.currentTarget, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes - - bulmaJS.alert({ - message: 'Work Order Milestone Type Updated Successfully', - contextualColorName: 'success' - }) - } else { - bulmaJS.alert({ - title: 'Error Updating Work Order Milestone Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) -} - -function deleteWorkOrderMilestoneType(clickEvent: Event): void { - const tableRowElement = (clickEvent.currentTarget as HTMLElement).closest( - 'tr' - ) as HTMLTableRowElement - - const workOrderMilestoneTypeId = - tableRowElement.dataset.workOrderMilestoneTypeId - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/admin/doDeleteWorkOrderMilestoneType`, - { - workOrderMilestoneTypeId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes - - if (workOrderMilestoneTypes.length === 0) { - renderWorkOrderMilestoneTypes() - } else { - tableRowElement.remove() - } - - bulmaJS.alert({ - message: 'Work Order Milestone Type Deleted Successfully', - contextualColorName: 'success' - }) - } else { - bulmaJS.alert({ - title: 'Error Deleting Work Order Milestone Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - bulmaJS.confirm({ - title: 'Delete Work Order Milestone Type', - message: `Are you sure you want to delete this work order milestone type?
- Note that no work orders will be removed.`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Work Order Milestone Type', - callbackFunction: doDelete - } - }) -} - -function moveWorkOrderMilestoneType(clickEvent: MouseEvent): void { - const buttonElement = clickEvent.currentTarget as HTMLButtonElement - - const tableRowElement = buttonElement.closest('tr') as HTMLTableRowElement - - const workOrderMilestoneTypeId = - tableRowElement.dataset.workOrderMilestoneTypeId - - cityssm.postJSON( - `${los.urlPrefix}/admin/${ - buttonElement.dataset.direction === 'up' - ? 'doMoveWorkOrderMilestoneTypeUp' - : 'doMoveWorkOrderMilestoneTypeDown' - }`, - { - workOrderMilestoneTypeId, - moveToEnd: clickEvent.shiftKey ? '1' : '0' - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes - renderWorkOrderMilestoneTypes() - } else { - bulmaJS.alert({ - title: 'Error Moving Work Order Milestone Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) -} - -function renderWorkOrderMilestoneTypes(): void { - const containerElement = document.querySelector( - '#container--workOrderMilestoneTypes' - ) as HTMLTableSectionElement - - if (workOrderMilestoneTypes.length === 0) { - containerElement.innerHTML = ` -

There are no active work order milestone types.

- ` - - return - } - - containerElement.innerHTML = '' - - for (const workOrderMilestoneType of workOrderMilestoneTypes) { - const tableRowElement = document.createElement('tr') - - tableRowElement.dataset.workOrderMilestoneTypeId = - workOrderMilestoneType.workOrderMilestoneTypeId.toString() - - // eslint-disable-next-line no-unsanitized/property, no-secrets/no-secrets - tableRowElement.innerHTML = ` -
- -
-
- -
-
- -
-
-
- -
-
- ${los.getMoveUpDownButtonFieldHTML( - 'button--moveWorkOrderMilestoneTypeUp', - 'button--moveWorkOrderMilestoneTypeDown', - false - )} -
-
- -
-
- ` - - tableRowElement - .querySelector('form') - ?.addEventListener('submit', updateWorkOrderMilestoneType) - ;( - tableRowElement.querySelector( - '.button--moveWorkOrderMilestoneTypeUp' - ) as HTMLButtonElement - ).addEventListener('click', moveWorkOrderMilestoneType) - ;( - tableRowElement.querySelector( - '.button--moveWorkOrderMilestoneTypeDown' - ) as HTMLButtonElement - ).addEventListener('click', moveWorkOrderMilestoneType) - - tableRowElement - .querySelector('.button--deleteWorkOrderMilestoneType') - ?.addEventListener('click', deleteWorkOrderMilestoneType) - - containerElement.append(tableRowElement) - } -} -;( - document.querySelector('#form--addWorkOrderMilestoneType') as HTMLFormElement -).addEventListener('submit', (submitEvent: SubmitEvent) => { - submitEvent.preventDefault() - - const formElement = submitEvent.currentTarget as HTMLFormElement - - cityssm.postJSON( - `${los.urlPrefix}/admin/doAddWorkOrderMilestoneType`, - formElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes - renderWorkOrderMilestoneTypes() - formElement.reset() - formElement.querySelector('input')?.focus() - } else { - bulmaJS.alert({ - title: 'Error Adding Work Order Milestone Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) -}) - -renderWorkOrderMilestoneTypes() diff --git a/public-typescript/adminTables/adminTablesWorkOrderTypes.d.ts b/public-typescript/adminTables/adminTablesWorkOrderTypes.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/public-typescript/adminTables/adminTablesWorkOrderTypes.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/public-typescript/adminTables/adminTablesWorkOrderTypes.js b/public-typescript/adminTables/adminTablesWorkOrderTypes.js deleted file mode 100644 index c2af7434..00000000 --- a/public-typescript/adminTables/adminTablesWorkOrderTypes.js +++ /dev/null @@ -1,166 +0,0 @@ -"use strict"; -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -let workOrderTypes = exports.workOrderTypes; -delete exports.workOrderTypes; -function updateWorkOrderType(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateWorkOrderType`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes; - bulmaJS.alert({ - message: 'Work Order Type Updated Successfully', - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: 'Error Updating Work Order Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); -} -function deleteWorkOrderType(clickEvent) { - const tableRowElement = clickEvent.currentTarget.closest('tr'); - const workOrderTypeId = tableRowElement.dataset.workOrderTypeId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteWorkOrderType`, { - workOrderTypeId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes; - if (workOrderTypes.length === 0) { - renderWorkOrderTypes(); - } - else { - tableRowElement.remove(); - } - bulmaJS.alert({ - message: 'Work Order Type Deleted Successfully', - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Work Order Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: 'Delete Work Order Type', - message: `Are you sure you want to delete this work order type?
- Note that no work orders will be removed.`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Work Order Type', - callbackFunction: doDelete - } - }); -} -function moveWorkOrderType(clickEvent) { - const buttonElement = clickEvent.currentTarget; - const tableRowElement = buttonElement.closest('tr'); - const workOrderTypeId = tableRowElement.dataset.workOrderTypeId; - cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' - ? 'doMoveWorkOrderTypeUp' - : 'doMoveWorkOrderTypeDown'}`, { - workOrderTypeId, - moveToEnd: clickEvent.shiftKey ? '1' : '0' - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes; - renderWorkOrderTypes(); - } - else { - bulmaJS.alert({ - title: 'Error Moving Work Order Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); -} -function renderWorkOrderTypes() { - const containerElement = document.querySelector('#container--workOrderTypes'); - if (workOrderTypes.length === 0) { - containerElement.innerHTML = ` -

There are no active work order types.

- `; - return; - } - containerElement.innerHTML = ''; - for (const workOrderType of workOrderTypes) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.workOrderTypeId = - workOrderType.workOrderTypeId.toString(); - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` -
- -
-
- -
-
- -
-
-
- -
-
- ${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderTypeUp', 'button--moveWorkOrderTypeDown', false)} -
-
- -
-
- `; - tableRowElement - .querySelector('form') - ?.addEventListener('submit', updateWorkOrderType); - tableRowElement.querySelector('.button--moveWorkOrderTypeUp').addEventListener('click', moveWorkOrderType); - tableRowElement.querySelector('.button--moveWorkOrderTypeDown').addEventListener('click', moveWorkOrderType); - tableRowElement - .querySelector('.button--deleteWorkOrderType') - ?.addEventListener('click', deleteWorkOrderType); - containerElement.append(tableRowElement); - } -} -; -document.querySelector('#form--addWorkOrderType').addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault(); - const formElement = submitEvent.currentTarget; - cityssm.postJSON(`${los.urlPrefix}/admin/doAddWorkOrderType`, formElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes; - renderWorkOrderTypes(); - formElement.reset(); - formElement.querySelector('input')?.focus(); - } - else { - bulmaJS.alert({ - title: 'Error Adding Work Order Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); -}); -renderWorkOrderTypes(); diff --git a/public-typescript/adminTables/adminTablesWorkOrderTypes.ts b/public-typescript/adminTables/adminTablesWorkOrderTypes.ts deleted file mode 100644 index 4ba13750..00000000 --- a/public-typescript/adminTables/adminTablesWorkOrderTypes.ts +++ /dev/null @@ -1,247 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ - -import type { BulmaJS } from '@cityssm/bulma-js/types.js' -import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' - -import type { LOS } from '../../types/globalTypes.js' -import type { WorkOrderType } from '../../types/recordTypes.js' - -declare const cityssm: cityssmGlobal -declare const bulmaJS: BulmaJS - -declare const los: LOS -declare const exports: Record - -let workOrderTypes = exports.workOrderTypes as WorkOrderType[] -delete exports.workOrderTypes - -type ResponseJSON = - | { - success: true - workOrderTypes: WorkOrderType[] - } - | { - success: false - errorMessage: string - } - -function updateWorkOrderType(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/admin/doUpdateWorkOrderType`, - submitEvent.currentTarget, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes - - bulmaJS.alert({ - message: 'Work Order Type Updated Successfully', - contextualColorName: 'success' - }) - } else { - bulmaJS.alert({ - title: 'Error Updating Work Order Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) -} - -function deleteWorkOrderType(clickEvent: Event): void { - const tableRowElement = (clickEvent.currentTarget as HTMLElement).closest( - 'tr' - ) as HTMLTableRowElement - - const workOrderTypeId = tableRowElement.dataset.workOrderTypeId - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/admin/doDeleteWorkOrderType`, - { - workOrderTypeId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes - - if (workOrderTypes.length === 0) { - renderWorkOrderTypes() - } else { - tableRowElement.remove() - } - - bulmaJS.alert({ - message: 'Work Order Type Deleted Successfully', - contextualColorName: 'success' - }) - } else { - bulmaJS.alert({ - title: 'Error Deleting Work Order Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - bulmaJS.confirm({ - title: 'Delete Work Order Type', - message: `Are you sure you want to delete this work order type?
- Note that no work orders will be removed.`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Work Order Type', - callbackFunction: doDelete - } - }) -} - -function moveWorkOrderType(clickEvent: MouseEvent): void { - const buttonElement = clickEvent.currentTarget as HTMLButtonElement - - const tableRowElement = buttonElement.closest('tr') as HTMLTableRowElement - - const workOrderTypeId = tableRowElement.dataset.workOrderTypeId - - cityssm.postJSON( - `${los.urlPrefix}/admin/${ - buttonElement.dataset.direction === 'up' - ? 'doMoveWorkOrderTypeUp' - : 'doMoveWorkOrderTypeDown' - }`, - { - workOrderTypeId, - moveToEnd: clickEvent.shiftKey ? '1' : '0' - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes - renderWorkOrderTypes() - } else { - bulmaJS.alert({ - title: 'Error Moving Work Order Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) -} - -function renderWorkOrderTypes(): void { - const containerElement = document.querySelector( - '#container--workOrderTypes' - ) as HTMLTableSectionElement - - if (workOrderTypes.length === 0) { - containerElement.innerHTML = ` -

There are no active work order types.

- ` - - return - } - - containerElement.innerHTML = '' - - for (const workOrderType of workOrderTypes) { - const tableRowElement = document.createElement('tr') - - tableRowElement.dataset.workOrderTypeId = - workOrderType.workOrderTypeId.toString() - - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` -
- -
-
- -
-
- -
-
-
- -
-
- ${los.getMoveUpDownButtonFieldHTML( - 'button--moveWorkOrderTypeUp', - 'button--moveWorkOrderTypeDown', - false - )} -
-
- -
-
- ` - - tableRowElement - .querySelector('form') - ?.addEventListener('submit', updateWorkOrderType) - ;( - tableRowElement.querySelector( - '.button--moveWorkOrderTypeUp' - ) as HTMLButtonElement - ).addEventListener('click', moveWorkOrderType) - ;( - tableRowElement.querySelector( - '.button--moveWorkOrderTypeDown' - ) as HTMLButtonElement - ).addEventListener('click', moveWorkOrderType) - - tableRowElement - .querySelector('.button--deleteWorkOrderType') - ?.addEventListener('click', deleteWorkOrderType) - - containerElement.append(tableRowElement) - } -} -;( - document.querySelector('#form--addWorkOrderType') as HTMLFormElement -).addEventListener('submit', (submitEvent: SubmitEvent) => { - submitEvent.preventDefault() - - const formElement = submitEvent.currentTarget as HTMLFormElement - - cityssm.postJSON( - `${los.urlPrefix}/admin/doAddWorkOrderType`, - formElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as ResponseJSON - - if (responseJSON.success) { - workOrderTypes = responseJSON.workOrderTypes - renderWorkOrderTypes() - formElement.reset() - formElement.querySelector('input')?.focus() - } else { - bulmaJS.alert({ - title: 'Error Adding Work Order Type', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) -}) - -renderWorkOrderTypes() diff --git a/public-typescript/lotOccupancyEdit.js b/public-typescript/lotOccupancyEdit.js deleted file mode 100644 index 02ddea8e..00000000 --- a/public-typescript/lotOccupancyEdit.js +++ /dev/null @@ -1,1729 +0,0 @@ -"use strict"; -/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */ -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -(() => { - const los = exports.los; - const lotOccupancyId = document.querySelector('#lotOccupancy--lotOccupancyId').value; - const isCreate = lotOccupancyId === ''; - /* - * Main form - */ - let refreshAfterSave = isCreate; - function setUnsavedChanges() { - los.setUnsavedChanges(); - document - .querySelector("button[type='submit'][form='form--lotOccupancy']") - ?.classList.remove('is-light'); - } - function clearUnsavedChanges() { - los.clearUnsavedChanges(); - document - .querySelector("button[type='submit'][form='form--lotOccupancy']") - ?.classList.add('is-light'); - } - const formElement = document.querySelector('#form--lotOccupancy'); - formElement.addEventListener('submit', (formEvent) => { - formEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/${isCreate ? 'doCreateLotOccupancy' : 'doUpdateLotOccupancy'}`, formElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - clearUnsavedChanges(); - if (isCreate || refreshAfterSave) { - window.location.href = los.getLotOccupancyURL(responseJSON.lotOccupancyId, true, true); - } - else { - bulmaJS.alert({ - message: `${los.escapedAliases.Occupancy} Updated Successfully`, - contextualColorName: 'success' - }); - } - } - else { - bulmaJS.alert({ - title: `Error Saving ${los.escapedAliases.Occupancy}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - }); - const formInputElements = formElement.querySelectorAll('input, select'); - for (const formInputElement of formInputElements) { - formInputElement.addEventListener('change', setUnsavedChanges); - } - function doCopy() { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doCopyLotOccupancy`, { - lotOccupancyId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - clearUnsavedChanges(); - window.location.href = los.getLotOccupancyURL(responseJSON.lotOccupancyId, true); - } - else { - bulmaJS.alert({ - title: 'Error Copying Record', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - document - .querySelector('#button--copyLotOccupancy') - ?.addEventListener('click', (clickEvent) => { - clickEvent.preventDefault(); - if (los.hasUnsavedChanges()) { - bulmaJS.alert({ - title: 'Unsaved Changes', - message: 'Please save all unsaved changes before continuing.', - contextualColorName: 'warning' - }); - } - else { - bulmaJS.confirm({ - title: `Copy ${los.escapedAliases.Occupancy} Record as New`, - message: 'Are you sure you want to copy this record to a new record?', - contextualColorName: 'info', - okButton: { - text: 'Yes, Copy', - callbackFunction: doCopy - } - }); - } - }); - document - .querySelector('#button--deleteLotOccupancy') - ?.addEventListener('click', (clickEvent) => { - clickEvent.preventDefault(); - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancy`, { - lotOccupancyId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - clearUnsavedChanges(); - window.location.href = los.getLotOccupancyURL(); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Record', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Occupancy} Record`, - message: 'Are you sure you want to delete this record?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete', - callbackFunction: doDelete - } - }); - }); - document - .querySelector('#button--createWorkOrder') - ?.addEventListener('click', (clickEvent) => { - clickEvent.preventDefault(); - let createCloseModalFunction; - function doCreate(formEvent) { - formEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/workOrders/doCreateWorkOrder`, formEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - createCloseModalFunction(); - bulmaJS.confirm({ - title: 'Work Order Created Successfully', - message: 'Would you like to open the work order now?', - contextualColorName: 'success', - okButton: { - text: 'Yes, Open the Work Order', - callbackFunction: () => { - window.location.href = los.getWorkOrderURL(responseJSON.workOrderId, true); - } - } - }); - } - else { - bulmaJS.alert({ - title: 'Error Creating Work Order', - message: responseJSON.errorMessage, - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-createWorkOrder', { - onshow(modalElement) { - ; - modalElement.querySelector('#workOrderCreate--lotOccupancyId').value = lotOccupancyId; - modalElement.querySelector('#workOrderCreate--workOrderOpenDateString').value = cityssm.dateToString(new Date()); - const workOrderTypeSelectElement = modalElement.querySelector('#workOrderCreate--workOrderTypeId'); - const workOrderTypes = exports - .workOrderTypes; - if (workOrderTypes.length === 1) { - workOrderTypeSelectElement.innerHTML = ''; - } - for (const workOrderType of workOrderTypes) { - const optionElement = document.createElement('option'); - optionElement.value = workOrderType.workOrderTypeId.toString(); - optionElement.textContent = workOrderType.workOrderType ?? ''; - workOrderTypeSelectElement.append(optionElement); - } - }, - onshown(modalElement, closeModalFunction) { - createCloseModalFunction = closeModalFunction; - bulmaJS.toggleHtmlClipped(); - modalElement.querySelector('#workOrderCreate--workOrderTypeId').focus(); - modalElement - .querySelector('form') - ?.addEventListener('submit', doCreate); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#button--createWorkOrder').focus(); - } - }); - }); - // Occupancy Type - const occupancyTypeIdElement = document.querySelector('#lotOccupancy--occupancyTypeId'); - if (isCreate) { - const lotOccupancyFieldsContainerElement = document.querySelector('#container--lotOccupancyFields'); - occupancyTypeIdElement.addEventListener('change', () => { - if (occupancyTypeIdElement.value === '') { - // eslint-disable-next-line no-unsanitized/property - lotOccupancyFieldsContainerElement.innerHTML = `
-

Select the ${los.escapedAliases.occupancy} type to load the available fields.

-
`; - return; - } - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doGetOccupancyTypeFields`, { - occupancyTypeId: occupancyTypeIdElement.value - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.occupancyTypeFields.length === 0) { - // eslint-disable-next-line no-unsanitized/property - lotOccupancyFieldsContainerElement.innerHTML = `
-

There are no additional fields for this ${los.escapedAliases.occupancy} type.

-
`; - return; - } - lotOccupancyFieldsContainerElement.innerHTML = ''; - let occupancyTypeFieldIds = ''; - for (const occupancyTypeField of responseJSON.occupancyTypeFields) { - occupancyTypeFieldIds += `,${occupancyTypeField.occupancyTypeFieldId.toString()}`; - const fieldName = `lotOccupancyFieldValue_${occupancyTypeField.occupancyTypeFieldId.toString()}`; - const fieldId = `lotOccupancy--${fieldName}`; - const fieldElement = document.createElement('div'); - fieldElement.className = 'field'; - fieldElement.innerHTML = `
`; - fieldElement.querySelector('label').textContent = occupancyTypeField.occupancyTypeField; - if ((occupancyTypeField.occupancyTypeFieldValues ?? '') === '') { - const inputElement = document.createElement('input'); - inputElement.className = 'input'; - inputElement.id = fieldId; - inputElement.name = fieldName; - inputElement.type = 'text'; - inputElement.required = occupancyTypeField.isRequired; - inputElement.minLength = - occupancyTypeField.minimumLength; - inputElement.maxLength = - occupancyTypeField.maximumLength; - if ((occupancyTypeField.pattern ?? '') !== '') { - inputElement.pattern = occupancyTypeField.pattern; - } - ; - fieldElement.querySelector('.control').append(inputElement); - } - else { - ; - fieldElement.querySelector('.control').innerHTML = `
- -
`; - const selectElement = fieldElement.querySelector('select'); - selectElement.required = occupancyTypeField.isRequired; - const optionValues = occupancyTypeField.occupancyTypeFieldValues.split('\n'); - for (const optionValue of optionValues) { - const optionElement = document.createElement('option'); - optionElement.value = optionValue; - optionElement.textContent = optionValue; - selectElement.append(optionElement); - } - } - console.log(fieldElement); - lotOccupancyFieldsContainerElement.append(fieldElement); - } - lotOccupancyFieldsContainerElement.insertAdjacentHTML('beforeend', - // eslint-disable-next-line no-secrets/no-secrets - ``); - }); - }); - } - else { - const originalOccupancyTypeId = occupancyTypeIdElement.value; - occupancyTypeIdElement.addEventListener('change', () => { - if (occupancyTypeIdElement.value !== originalOccupancyTypeId) { - bulmaJS.confirm({ - title: 'Confirm Change', - message: `Are you sure you want to change the ${los.escapedAliases.occupancy} type?\n - This change affects the additional fields associated with this record, and may also affect the available fees.`, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Keep the Change', - callbackFunction: () => { - refreshAfterSave = true; - } - }, - cancelButton: { - text: 'Revert the Change', - callbackFunction: () => { - occupancyTypeIdElement.value = originalOccupancyTypeId; - } - } - }); - } - }); - } - // Lot Selector - const lotNameElement = document.querySelector('#lotOccupancy--lotName'); - lotNameElement.addEventListener('click', (clickEvent) => { - const currentLotName = clickEvent.currentTarget.value; - let lotSelectCloseModalFunction; - let lotSelectModalElement; - let lotSelectFormElement; - let lotSelectResultsElement; - function renderSelectedLotAndClose(lotId, lotName) { - ; - document.querySelector('#lotOccupancy--lotId').value = lotId.toString(); - document.querySelector('#lotOccupancy--lotName').value = lotName; - setUnsavedChanges(); - lotSelectCloseModalFunction(); - } - function selectExistingLot(clickEvent) { - clickEvent.preventDefault(); - const selectedLotElement = clickEvent.currentTarget; - renderSelectedLotAndClose(selectedLotElement.dataset.lotId ?? '', selectedLotElement.dataset.lotName ?? ''); - } - function searchLots() { - // eslint-disable-next-line no-unsanitized/property - lotSelectResultsElement.innerHTML = - los.getLoadingParagraphHTML('Searching...'); - cityssm.postJSON(`${los.urlPrefix}/lots/doSearchLots`, lotSelectFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.count === 0) { - lotSelectResultsElement.innerHTML = `
-

No results.

-
`; - return; - } - const panelElement = document.createElement('div'); - panelElement.className = 'panel'; - for (const lot of responseJSON.lots) { - const panelBlockElement = document.createElement('a'); - panelBlockElement.className = 'panel-block is-block'; - panelBlockElement.href = '#'; - panelBlockElement.dataset.lotId = lot.lotId.toString(); - panelBlockElement.dataset.lotName = lot.lotName; - // eslint-disable-next-line no-unsanitized/property - panelBlockElement.innerHTML = `
-
- ${cityssm.escapeHTML(lot.lotName ?? '')}
- ${cityssm.escapeHTML(lot.mapName ?? '')} -
-
- ${cityssm.escapeHTML(lot.lotStatus)}
- - ${lot.lotOccupancyCount > 0 ? 'Currently Occupied' : ''} - -
-
`; - panelBlockElement.addEventListener('click', selectExistingLot); - panelElement.append(panelBlockElement); - } - lotSelectResultsElement.innerHTML = ''; - lotSelectResultsElement.append(panelElement); - }); - } - function createLotAndSelect(submitEvent) { - submitEvent.preventDefault(); - const lotName = lotSelectModalElement.querySelector('#lotCreate--lotName').value; - cityssm.postJSON(`${los.urlPrefix}/lots/doCreateLot`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - renderSelectedLotAndClose(responseJSON.lotId ?? '', lotName); - } - else { - bulmaJS.alert({ - title: `Error Creating ${los.escapedAliases.Lot}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-selectLot', { - onshow(modalElement) { - los.populateAliases(modalElement); - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - lotSelectModalElement = modalElement; - lotSelectCloseModalFunction = closeModalFunction; - bulmaJS.init(modalElement); - // search Tab - const lotNameFilterElement = modalElement.querySelector('#lotSelect--lotName'); - if (document.querySelector('#lotOccupancy--lotId') - .value !== '') { - lotNameFilterElement.value = currentLotName; - } - lotNameFilterElement.focus(); - lotNameFilterElement.addEventListener('change', searchLots); - const occupancyStatusFilterElement = modalElement.querySelector('#lotSelect--occupancyStatus'); - occupancyStatusFilterElement.addEventListener('change', searchLots); - if (currentLotName !== '') { - occupancyStatusFilterElement.value = ''; - } - lotSelectFormElement = modalElement.querySelector('#form--lotSelect'); - lotSelectResultsElement = modalElement.querySelector('#resultsContainer--lotSelect'); - lotSelectFormElement.addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault(); - }); - searchLots(); - // Create Tab - if (exports.lotNamePattern) { - const regex = exports.lotNamePattern; - modalElement.querySelector('#lotCreate--lotName').pattern = regex.source; - } - const lotTypeElement = modalElement.querySelector('#lotCreate--lotTypeId'); - for (const lotType of exports.lotTypes) { - const optionElement = document.createElement('option'); - optionElement.value = lotType.lotTypeId.toString(); - optionElement.textContent = lotType.lotType; - lotTypeElement.append(optionElement); - } - const lotStatusElement = modalElement.querySelector('#lotCreate--lotStatusId'); - for (const lotStatus of exports.lotStatuses) { - const optionElement = document.createElement('option'); - optionElement.value = lotStatus.lotStatusId.toString(); - optionElement.textContent = lotStatus.lotStatus; - lotStatusElement.append(optionElement); - } - const mapElement = modalElement.querySelector('#lotCreate--mapId'); - for (const map of exports.maps) { - const optionElement = document.createElement('option'); - optionElement.value = map.mapId.toString(); - optionElement.textContent = - (map.mapName ?? '') === '' ? '(No Name)' : map.mapName ?? ''; - mapElement.append(optionElement); - } - ; - modalElement.querySelector('#form--lotCreate').addEventListener('submit', createLotAndSelect); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); - }); - document - .querySelector('.is-lot-view-button') - ?.addEventListener('click', () => { - const lotId = document.querySelector('#lotOccupancy--lotId').value; - if (lotId === '') { - bulmaJS.alert({ - message: `No ${los.escapedAliases.lot} selected.`, - contextualColorName: 'info' - }); - } - else { - window.open(`${los.urlPrefix}/lots/${lotId}`); - } - }); - document - .querySelector('.is-clear-lot-button') - ?.addEventListener('click', () => { - if (lotNameElement.disabled) { - bulmaJS.alert({ - message: 'You need to unlock the field before clearing it.', - contextualColorName: 'info' - }); - } - else { - lotNameElement.value = `(No ${los.escapedAliases.Lot})`; - document.querySelector('#lotOccupancy--lotId').value = ''; - setUnsavedChanges(); - } - }); - // Start Date - los.initializeDatePickers(formElement); - document - .querySelector('#lotOccupancy--occupancyStartDateString') - ?.addEventListener('change', () => { - const endDatePicker = document.querySelector('#lotOccupancy--occupancyEndDateString').bulmaCalendar.datePicker; - endDatePicker.min = document.querySelector('#lotOccupancy--occupancyStartDateString').value; - endDatePicker.refresh(); - }); - los.initializeUnlockFieldButtons(formElement); - /* - * Occupants - */ - "use strict"; - // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair - /* eslint-disable unicorn/prefer-module */ - Object.defineProperty(exports, "__esModule", { value: true }); - let lotOccupancyOccupants = exports.lotOccupancyOccupants; - delete exports.lotOccupancyOccupants; - function openEditLotOccupancyOccupant(clickEvent) { - const lotOccupantIndex = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .lotOccupantIndex ?? '', 10); - const lotOccupancyOccupant = lotOccupancyOccupants.find((currentLotOccupancyOccupant) => { - return currentLotOccupancyOccupant.lotOccupantIndex === lotOccupantIndex; - }); - let editFormElement; - let editCloseModalFunction; - function editOccupant(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyOccupant`, editFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyOccupants = responseJSON.lotOccupancyOccupants; - editCloseModalFunction(); - renderLotOccupancyOccupants(); - } - else { - bulmaJS.alert({ - title: `Error Updating ${los.escapedAliases.Occupant}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-editOccupant', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotOccupancyOccupantEdit--lotOccupancyId').value = lotOccupancyId; - modalElement.querySelector('#lotOccupancyOccupantEdit--lotOccupantIndex').value = lotOccupantIndex.toString(); - const lotOccupantTypeSelectElement = modalElement.querySelector('#lotOccupancyOccupantEdit--lotOccupantTypeId'); - let lotOccupantTypeSelected = false; - for (const lotOccupantType of exports.lotOccupantTypes) { - const optionElement = document.createElement('option'); - optionElement.value = lotOccupantType.lotOccupantTypeId.toString(); - optionElement.textContent = lotOccupantType.lotOccupantType; - optionElement.dataset.occupantCommentTitle = - lotOccupantType.occupantCommentTitle; - optionElement.dataset.fontAwesomeIconClass = - lotOccupantType.fontAwesomeIconClass; - if (lotOccupantType.lotOccupantTypeId === - lotOccupancyOccupant.lotOccupantTypeId) { - optionElement.selected = true; - lotOccupantTypeSelected = true; - } - lotOccupantTypeSelectElement.append(optionElement); - } - if (!lotOccupantTypeSelected) { - const optionElement = document.createElement('option'); - optionElement.value = - lotOccupancyOccupant.lotOccupantTypeId?.toString() ?? ''; - optionElement.textContent = lotOccupancyOccupant.lotOccupantType ?? ''; - optionElement.dataset.occupantCommentTitle = - lotOccupancyOccupant.occupantCommentTitle; - optionElement.dataset.fontAwesomeIconClass = - lotOccupancyOccupant.fontAwesomeIconClass; - optionElement.selected = true; - lotOccupantTypeSelectElement.append(optionElement); - } - ; - modalElement.querySelector('#lotOccupancyOccupantEdit--fontAwesomeIconClass').innerHTML = - ``; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantName').value = lotOccupancyOccupant.occupantName ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantFamilyName').value = lotOccupancyOccupant.occupantFamilyName ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantAddress1').value = lotOccupancyOccupant.occupantAddress1 ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantAddress2').value = lotOccupancyOccupant.occupantAddress2 ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantCity').value = lotOccupancyOccupant.occupantCity ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantProvince').value = lotOccupancyOccupant.occupantProvince ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantPostalCode').value = lotOccupancyOccupant.occupantPostalCode ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantPhoneNumber').value = lotOccupancyOccupant.occupantPhoneNumber ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantEmailAddress').value = lotOccupancyOccupant.occupantEmailAddress ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantCommentTitle').textContent = - (lotOccupancyOccupant.occupantCommentTitle ?? '') === '' - ? 'Comment' - : lotOccupancyOccupant.occupantCommentTitle ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantComment').value = lotOccupancyOccupant.occupantComment ?? ''; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - const lotOccupantTypeIdElement = modalElement.querySelector('#lotOccupancyOccupantEdit--lotOccupantTypeId'); - lotOccupantTypeIdElement.focus(); - lotOccupantTypeIdElement.addEventListener('change', () => { - const fontAwesomeIconClass = lotOccupantTypeIdElement.selectedOptions[0].dataset - .fontAwesomeIconClass ?? 'user'; - modalElement.querySelector('#lotOccupancyOccupantEdit--fontAwesomeIconClass').innerHTML = - ``; - let occupantCommentTitle = lotOccupantTypeIdElement.selectedOptions[0].dataset - .occupantCommentTitle ?? ''; - if (occupantCommentTitle === '') { - occupantCommentTitle = 'Comment'; - } - ; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantCommentTitle').textContent = occupantCommentTitle; - }); - editFormElement = modalElement.querySelector('form'); - editFormElement.addEventListener('submit', editOccupant); - editCloseModalFunction = closeModalFunction; - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); - } - function deleteLotOccupancyOccupant(clickEvent) { - const lotOccupantIndex = clickEvent.currentTarget.closest('tr')?.dataset.lotOccupantIndex; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyOccupant`, { - lotOccupancyId, - lotOccupantIndex - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyOccupants = responseJSON.lotOccupancyOccupants; - renderLotOccupancyOccupants(); - } - else { - bulmaJS.alert({ - title: `Error Removing ${los.escapedAliases.Occupant}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: `Remove ${los.escapedAliases.Occupant}?`, - message: `Are you sure you want to remove this ${los.escapedAliases.occupant}?`, - okButton: { - text: `Yes, Remove ${los.escapedAliases.Occupant}`, - callbackFunction: doDelete - }, - contextualColorName: 'warning' - }); - } - function renderLotOccupancyOccupants() { - const occupantsContainer = document.querySelector('#container--lotOccupancyOccupants'); - cityssm.clearElement(occupantsContainer); - if (lotOccupancyOccupants.length === 0) { - // eslint-disable-next-line no-unsanitized/property - occupantsContainer.innerHTML = `
-

There are no ${los.escapedAliases.occupants} associated with this record.

-
`; - return; - } - const tableElement = document.createElement('table'); - tableElement.className = 'table is-fullwidth is-striped is-hoverable'; - // eslint-disable-next-line no-unsanitized/property - tableElement.innerHTML = ` - ${los.escapedAliases.Occupant} - Address - Other Contact - Comment - Options - - `; - for (const lotOccupancyOccupant of lotOccupancyOccupants) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.lotOccupantIndex = - lotOccupancyOccupant.lotOccupantIndex?.toString(); - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` - ${cityssm.escapeHTML((lotOccupancyOccupant.occupantName ?? '') === '' && - (lotOccupancyOccupant.occupantFamilyName ?? '') === '' - ? '(No Name)' - : `${lotOccupancyOccupant.occupantName} ${lotOccupancyOccupant.occupantFamilyName}`)}
- - - ${cityssm.escapeHTML(lotOccupancyOccupant.lotOccupantType ?? '')} - - - ${(lotOccupancyOccupant.occupantAddress1 ?? '') === '' - ? '' - : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress1 ?? '')}
`} - ${(lotOccupancyOccupant.occupantAddress2 ?? '') === '' - ? '' - : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress2 ?? '')}
`} - ${(lotOccupancyOccupant.occupantCity ?? '') === '' - ? '' - : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantCity ?? '')}, `} - ${cityssm.escapeHTML(lotOccupancyOccupant.occupantProvince ?? '')}
- ${cityssm.escapeHTML(lotOccupancyOccupant.occupantPostalCode ?? '')} - - ${(lotOccupancyOccupant.occupantPhoneNumber ?? '') === '' - ? '' - : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantPhoneNumber ?? '')}
`} - ${(lotOccupancyOccupant.occupantEmailAddress ?? '') === '' - ? '' - : cityssm.escapeHTML(lotOccupancyOccupant.occupantEmailAddress ?? '')} - - - ${cityssm.escapeHTML(lotOccupancyOccupant.occupantComment ?? '')} - - -
- - -
- `; - tableRowElement - .querySelector('.button--edit') - ?.addEventListener('click', openEditLotOccupancyOccupant); - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteLotOccupancyOccupant); - tableElement.querySelector('tbody')?.append(tableRowElement); - } - occupantsContainer.append(tableElement); - } - if (isCreate) { - const lotOccupantTypeIdElement = document.querySelector('#lotOccupancy--lotOccupantTypeId'); - lotOccupantTypeIdElement.addEventListener('change', () => { - const occupantFields = formElement.querySelectorAll("[data-table='LotOccupancyOccupant']"); - for (const occupantField of occupantFields) { - occupantField.disabled = lotOccupantTypeIdElement.value === ''; - } - let occupantCommentTitle = lotOccupantTypeIdElement.selectedOptions[0].dataset - .occupantCommentTitle ?? ''; - if (occupantCommentTitle === '') { - occupantCommentTitle = 'Comment'; - } - ; - formElement.querySelector('#lotOccupancy--occupantCommentTitle').textContent = occupantCommentTitle; - }); - } - else { - renderLotOccupancyOccupants(); - } - document - .querySelector('#button--addOccupant') - ?.addEventListener('click', () => { - let addCloseModalFunction; - let addFormElement; - let searchFormElement; - let searchResultsElement; - function addOccupant(formOrObject) { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyOccupant`, formOrObject, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyOccupants = responseJSON.lotOccupancyOccupants; - addCloseModalFunction(); - renderLotOccupancyOccupants(); - } - else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Occupant}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function addOccupantFromForm(submitEvent) { - submitEvent.preventDefault(); - addOccupant(addFormElement); - } - let pastOccupantSearchResults = []; - function addOccupantFromCopy(clickEvent) { - clickEvent.preventDefault(); - const panelBlockElement = clickEvent.currentTarget; - const occupant = pastOccupantSearchResults[Number.parseInt(panelBlockElement.dataset.index ?? '', 10)]; - const lotOccupantTypeId = (panelBlockElement - .closest('.modal') - ?.querySelector('#lotOccupancyOccupantCopy--lotOccupantTypeId')).value; - if (lotOccupantTypeId === '') { - bulmaJS.alert({ - title: `No ${los.escapedAliases.Occupant} Type Selected`, - message: `Select a type to apply to the newly added ${los.escapedAliases.occupant}.`, - contextualColorName: 'warning' - }); - } - else { - occupant.lotOccupantTypeId = Number.parseInt(lotOccupantTypeId, 10); - occupant.lotOccupancyId = Number.parseInt(lotOccupancyId, 10); - addOccupant(occupant); - } - } - function searchOccupants(event) { - event.preventDefault(); - if (searchFormElement.querySelector('#lotOccupancyOccupantCopy--searchFilter').value === '') { - searchResultsElement.innerHTML = `
-

Enter a partial name or address in the search field above.

-
`; - return; - } - // eslint-disable-next-line no-unsanitized/property - searchResultsElement.innerHTML = - los.getLoadingParagraphHTML('Searching...'); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doSearchPastOccupants`, searchFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - pastOccupantSearchResults = responseJSON.occupants; - const panelElement = document.createElement('div'); - panelElement.className = 'panel'; - for (const [index, occupant] of pastOccupantSearchResults.entries()) { - const panelBlockElement = document.createElement('a'); - panelBlockElement.className = 'panel-block is-block'; - panelBlockElement.href = '#'; - panelBlockElement.dataset.index = index.toString(); - // eslint-disable-next-line no-unsanitized/property - panelBlockElement.innerHTML = ` - ${cityssm.escapeHTML(occupant.occupantName ?? '')} ${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')} -
-
-
- ${cityssm.escapeHTML(occupant.occupantAddress1 ?? '')}
- ${(occupant.occupantAddress2 ?? '') === '' - ? '' - : `${cityssm.escapeHTML(occupant.occupantAddress2 ?? '')}
`}${cityssm.escapeHTML(occupant.occupantCity ?? '')}, ${cityssm.escapeHTML(occupant.occupantProvince ?? '')}
- ${cityssm.escapeHTML(occupant.occupantPostalCode ?? '')} -
-
- ${(occupant.occupantPhoneNumber ?? '') === '' - ? '' - : `${cityssm.escapeHTML(occupant.occupantPhoneNumber ?? '')}
`} - ${cityssm.escapeHTML(occupant.occupantEmailAddress ?? '')}
-
-
`; - panelBlockElement.addEventListener('click', addOccupantFromCopy); - panelElement.append(panelBlockElement); - } - searchResultsElement.innerHTML = ''; - searchResultsElement.append(panelElement); - }); - } - cityssm.openHtmlModal('lotOccupancy-addOccupant', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotOccupancyOccupantAdd--lotOccupancyId').value = lotOccupancyId; - const lotOccupantTypeSelectElement = modalElement.querySelector('#lotOccupancyOccupantAdd--lotOccupantTypeId'); - const lotOccupantTypeCopySelectElement = modalElement.querySelector('#lotOccupancyOccupantCopy--lotOccupantTypeId'); - for (const lotOccupantType of exports.lotOccupantTypes) { - const optionElement = document.createElement('option'); - optionElement.value = lotOccupantType.lotOccupantTypeId.toString(); - optionElement.textContent = lotOccupantType.lotOccupantType; - optionElement.dataset.occupantCommentTitle = - lotOccupantType.occupantCommentTitle; - optionElement.dataset.fontAwesomeIconClass = - lotOccupantType.fontAwesomeIconClass; - lotOccupantTypeSelectElement.append(optionElement); - lotOccupantTypeCopySelectElement.append(optionElement.cloneNode(true)); - } - ; - modalElement.querySelector('#lotOccupancyOccupantAdd--occupantCity').value = exports.occupantCityDefault; - modalElement.querySelector('#lotOccupancyOccupantAdd--occupantProvince').value = exports.occupantProvinceDefault; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - bulmaJS.init(modalElement); - const lotOccupantTypeIdElement = modalElement.querySelector('#lotOccupancyOccupantAdd--lotOccupantTypeId'); - lotOccupantTypeIdElement.focus(); - lotOccupantTypeIdElement.addEventListener('change', () => { - const fontAwesomeIconClass = lotOccupantTypeIdElement.selectedOptions[0].dataset - .fontAwesomeIconClass ?? 'user'; - modalElement.querySelector('#lotOccupancyOccupantAdd--fontAwesomeIconClass').innerHTML = - ``; - let occupantCommentTitle = lotOccupantTypeIdElement.selectedOptions[0].dataset - .occupantCommentTitle ?? ''; - if (occupantCommentTitle === '') { - occupantCommentTitle = 'Comment'; - } - ; - modalElement.querySelector('#lotOccupancyOccupantAdd--occupantCommentTitle').textContent = occupantCommentTitle; - }); - addFormElement = modalElement.querySelector('#form--lotOccupancyOccupantAdd'); - addFormElement.addEventListener('submit', addOccupantFromForm); - searchResultsElement = modalElement.querySelector('#lotOccupancyOccupantCopy--searchResults'); - searchFormElement = modalElement.querySelector('#form--lotOccupancyOccupantCopy'); - searchFormElement.addEventListener('submit', (formEvent) => { - formEvent.preventDefault(); - }); - modalElement.querySelector('#lotOccupancyOccupantCopy--searchFilter').addEventListener('change', searchOccupants); - addCloseModalFunction = closeModalFunction; - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#button--addOccupant').focus(); - } - }); - }); - - if (!isCreate) { - "use strict"; - // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair - /* eslint-disable unicorn/prefer-module */ - Object.defineProperty(exports, "__esModule", { value: true }); - let lotOccupancyComments = exports.lotOccupancyComments; - delete exports.lotOccupancyComments; - function openEditLotOccupancyComment(clickEvent) { - const lotOccupancyCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .lotOccupancyCommentId ?? '', 10); - const lotOccupancyComment = lotOccupancyComments.find((currentLotOccupancyComment) => { - return (currentLotOccupancyComment.lotOccupancyCommentId === - lotOccupancyCommentId); - }); - let editFormElement; - let editCloseModalFunction; - function editComment(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyComment`, editFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyComments = responseJSON.lotOccupancyComments ?? []; - editCloseModalFunction(); - renderLotOccupancyComments(); - } - else { - bulmaJS.alert({ - title: 'Error Updating Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-editComment', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyId').value = lotOccupancyId; - modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyCommentId').value = lotOccupancyCommentId.toString(); - modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyComment').value = lotOccupancyComment.lotOccupancyComment ?? ''; - const lotOccupancyCommentDateStringElement = modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyCommentDateString'); - lotOccupancyCommentDateStringElement.value = - lotOccupancyComment.lotOccupancyCommentDateString ?? ''; - const currentDateString = cityssm.dateToString(new Date()); - lotOccupancyCommentDateStringElement.max = - lotOccupancyComment.lotOccupancyCommentDateString <= currentDateString - ? currentDateString - : lotOccupancyComment.lotOccupancyCommentDateString ?? ''; - modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyCommentTimeString').value = lotOccupancyComment.lotOccupancyCommentTimeString ?? ''; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - los.initializeDatePickers(modalElement); - modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyComment').focus(); - editFormElement = modalElement.querySelector('form'); - editFormElement.addEventListener('submit', editComment); - editCloseModalFunction = closeModalFunction; - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); - } - function deleteLotOccupancyComment(clickEvent) { - const lotOccupancyCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .lotOccupancyCommentId ?? '', 10); - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyComment`, { - lotOccupancyId, - lotOccupancyCommentId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyComments = responseJSON.lotOccupancyComments; - renderLotOccupancyComments(); - } - else { - bulmaJS.alert({ - title: 'Error Removing Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: 'Remove Comment?', - message: 'Are you sure you want to remove this comment?', - okButton: { - text: 'Yes, Remove Comment', - callbackFunction: doDelete - }, - contextualColorName: 'warning' - }); - } - function renderLotOccupancyComments() { - const containerElement = document.querySelector('#container--lotOccupancyComments'); - if (lotOccupancyComments.length === 0) { - containerElement.innerHTML = `
-

There are no comments associated with this record.

-
`; - return; - } - const tableElement = document.createElement('table'); - tableElement.className = 'table is-fullwidth is-striped is-hoverable'; - tableElement.innerHTML = ` - Commentor - Comment Date - Comment - Options - - `; - for (const lotOccupancyComment of lotOccupancyComments) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.lotOccupancyCommentId = - lotOccupancyComment.lotOccupancyCommentId?.toString(); - tableRowElement.innerHTML = `${cityssm.escapeHTML(lotOccupancyComment.recordCreate_userName ?? '')} - - ${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyCommentDateString ?? '')} - ${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyCommentTime === 0 - ? '' - : lotOccupancyComment.lotOccupancyCommentTimePeriodString ?? '')} - - ${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyComment ?? '')} - -
- - -
- `; - tableRowElement - .querySelector('.button--edit') - ?.addEventListener('click', openEditLotOccupancyComment); - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteLotOccupancyComment); - tableElement.querySelector('tbody')?.append(tableRowElement); - } - containerElement.innerHTML = ''; - containerElement.append(tableElement); - } - document.querySelector('#button--addComment')?.addEventListener('click', () => { - let addFormElement; - let addCloseModalFunction; - function addComment(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyComment`, addFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyComments = responseJSON.lotOccupancyComments; - addCloseModalFunction(); - renderLotOccupancyComments(); - } - else { - bulmaJS.alert({ - title: 'Error Adding Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-addComment', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotOccupancyCommentAdd--lotOccupancyId').value = lotOccupancyId; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - modalElement.querySelector('#lotOccupancyCommentAdd--lotOccupancyComment').focus(); - addFormElement = modalElement.querySelector('form'); - addFormElement.addEventListener('submit', addComment); - addCloseModalFunction = closeModalFunction; - }, - onremoved: () => { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#button--addComment').focus(); - } - }); - }); - renderLotOccupancyComments(); - - "use strict"; - // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair - /* eslint-disable unicorn/prefer-module */ - Object.defineProperty(exports, "__esModule", { value: true }); - let lotOccupancyFees = exports.lotOccupancyFees; - delete exports.lotOccupancyFees; - const lotOccupancyFeesContainerElement = document.querySelector('#container--lotOccupancyFees'); - function getFeeGrandTotal() { - let feeGrandTotal = 0; - for (const lotOccupancyFee of lotOccupancyFees) { - feeGrandTotal += - ((lotOccupancyFee.feeAmount ?? 0) + (lotOccupancyFee.taxAmount ?? 0)) * - (lotOccupancyFee.quantity ?? 0); - } - return feeGrandTotal; - } - function editLotOccupancyFeeQuantity(clickEvent) { - const feeId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .feeId ?? '', 10); - const fee = lotOccupancyFees.find((possibleFee) => { - return possibleFee.feeId === feeId; - }); - let updateCloseModalFunction; - function doUpdateQuantity(formEvent) { - formEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyFeeQuantity`, formEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyFees = responseJSON.lotOccupancyFees; - renderLotOccupancyFees(); - updateCloseModalFunction(); - } - else { - bulmaJS.alert({ - title: 'Error Updating Quantity', - message: 'Please try again.', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-editFeeQuantity', { - onshow(modalElement) { - ; - modalElement.querySelector('#lotOccupancyFeeQuantity--lotOccupancyId').value = lotOccupancyId; - modalElement.querySelector('#lotOccupancyFeeQuantity--feeId').value = fee.feeId.toString(); - modalElement.querySelector('#lotOccupancyFeeQuantity--quantity').valueAsNumber = fee.quantity ?? 0; - modalElement.querySelector('#lotOccupancyFeeQuantity--quantityUnit').textContent = fee.quantityUnit ?? ''; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - updateCloseModalFunction = closeModalFunction; - modalElement.querySelector('#lotOccupancyFeeQuantity--quantity').focus(); - modalElement - .querySelector('form') - ?.addEventListener('submit', doUpdateQuantity); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); - } - function deleteLotOccupancyFee(clickEvent) { - const feeId = clickEvent.currentTarget.closest('.container--lotOccupancyFee').dataset.feeId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyFee`, { - lotOccupancyId, - feeId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyFees = responseJSON.lotOccupancyFees; - renderLotOccupancyFees(); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Fee', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: 'Delete Fee', - message: 'Are you sure you want to delete this fee?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Fee', - callbackFunction: doDelete - } - }); - } - function renderLotOccupancyFees() { - if (lotOccupancyFees.length === 0) { - lotOccupancyFeesContainerElement.innerHTML = `
-

There are no fees associated with this record.

-
`; - renderLotOccupancyTransactions(); - return; - } - // eslint-disable-next-line no-secrets/no-secrets - lotOccupancyFeesContainerElement.innerHTML = ` - - - - - - - - - - - - - - - - - - - - - - -
FeeUnit Cost×QuantityequalsTotalOptions
Subtotal
Tax
Grand Total
`; - let feeAmountTotal = 0; - let taxAmountTotal = 0; - for (const lotOccupancyFee of lotOccupancyFees) { - const tableRowElement = document.createElement('tr'); - tableRowElement.className = 'container--lotOccupancyFee'; - tableRowElement.dataset.feeId = lotOccupancyFee.feeId.toString(); - tableRowElement.dataset.includeQuantity = - lotOccupancyFee.includeQuantity ?? false ? '1' : '0'; - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` - ${cityssm.escapeHTML(lotOccupancyFee.feeName ?? '')}
- ${cityssm.escapeHTML(lotOccupancyFee.feeCategory ?? '')} - - ${lotOccupancyFee.quantity === 1 - ? '' - : ` - $${lotOccupancyFee.feeAmount?.toFixed(2)} - - × - ${lotOccupancyFee.quantity?.toString()} - =`} - - $${((lotOccupancyFee.feeAmount ?? 0) * (lotOccupancyFee.quantity ?? 0)).toFixed(2)} - - -
- ${lotOccupancyFee.includeQuantity ?? false - ? `` - : ''} - -
- `; - tableRowElement - .querySelector('.button--editQuantity') - ?.addEventListener('click', editLotOccupancyFeeQuantity); - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteLotOccupancyFee); - lotOccupancyFeesContainerElement - .querySelector('tbody') - ?.append(tableRowElement); - feeAmountTotal += - (lotOccupancyFee.feeAmount ?? 0) * (lotOccupancyFee.quantity ?? 0); - taxAmountTotal += - (lotOccupancyFee.taxAmount ?? 0) * (lotOccupancyFee.quantity ?? 0); - } - ; - lotOccupancyFeesContainerElement.querySelector('#lotOccupancyFees--feeAmountTotal').textContent = `$${feeAmountTotal.toFixed(2)}`; - lotOccupancyFeesContainerElement.querySelector('#lotOccupancyFees--taxAmountTotal').textContent = `$${taxAmountTotal.toFixed(2)}`; - lotOccupancyFeesContainerElement.querySelector('#lotOccupancyFees--grandTotal').textContent = `$${(feeAmountTotal + taxAmountTotal).toFixed(2)}`; - renderLotOccupancyTransactions(); - } - const addFeeButtonElement = document.querySelector('#button--addFee'); - addFeeButtonElement.addEventListener('click', () => { - if (los.hasUnsavedChanges()) { - bulmaJS.alert({ - message: 'Please save all unsaved changes before adding fees.', - contextualColorName: 'warning' - }); - return; - } - let feeCategories; - let feeFilterElement; - let feeFilterResultsElement; - function doAddFeeCategory(clickEvent) { - clickEvent.preventDefault(); - const feeCategoryId = Number.parseInt(clickEvent.currentTarget.dataset.feeCategoryId ?? '', 10); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyFeeCategory`, { - lotOccupancyId, - feeCategoryId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyFees = responseJSON.lotOccupancyFees; - renderLotOccupancyFees(); - bulmaJS.alert({ - message: 'Fee Group Added Successfully', - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: 'Error Adding Fee', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function doAddFee(feeId, quantity = 1) { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyFee`, { - lotOccupancyId, - feeId, - quantity - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyFees = responseJSON.lotOccupancyFees; - renderLotOccupancyFees(); - filterFees(); - } - else { - bulmaJS.alert({ - title: 'Error Adding Fee', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function doSetQuantityAndAddFee(fee) { - let quantityElement; - let quantityCloseModalFunction; - function doSetQuantity(submitEvent) { - submitEvent.preventDefault(); - doAddFee(fee.feeId, quantityElement.value); - quantityCloseModalFunction(); - } - cityssm.openHtmlModal('lotOccupancy-setFeeQuantity', { - onshow(modalElement) { - ; - modalElement.querySelector('#lotOccupancyFeeQuantity--quantityUnit').textContent = fee.quantityUnit ?? ''; - }, - onshown(modalElement, closeModalFunction) { - quantityCloseModalFunction = closeModalFunction; - quantityElement = modalElement.querySelector('#lotOccupancyFeeQuantity--quantity'); - modalElement - .querySelector('form') - ?.addEventListener('submit', doSetQuantity); - } - }); - } - function tryAddFee(clickEvent) { - clickEvent.preventDefault(); - const feeId = Number.parseInt(clickEvent.currentTarget.dataset.feeId ?? '', 10); - const feeCategoryId = Number.parseInt(clickEvent.currentTarget.dataset.feeCategoryId ?? '', 10); - const feeCategory = feeCategories.find((currentFeeCategory) => { - return currentFeeCategory.feeCategoryId === feeCategoryId; - }); - const fee = feeCategory.fees.find((currentFee) => { - return currentFee.feeId === feeId; - }); - if (fee.includeQuantity ?? false) { - doSetQuantityAndAddFee(fee); - } - else { - doAddFee(feeId); - } - } - function filterFees() { - const filterStringPieces = feeFilterElement.value - .trim() - .toLowerCase() - .split(' '); - feeFilterResultsElement.innerHTML = ''; - for (const feeCategory of feeCategories) { - const categoryContainerElement = document.createElement('div'); - categoryContainerElement.className = 'container--feeCategory'; - categoryContainerElement.dataset.feeCategoryId = - feeCategory.feeCategoryId.toString(); - categoryContainerElement.innerHTML = `
-
-

- ${cityssm.escapeHTML(feeCategory.feeCategory ?? '')} -

-
-
-
`; - if (feeCategory.isGroupedFee) { - // eslint-disable-next-line no-unsanitized/method - categoryContainerElement.querySelector('.columns')?.insertAdjacentHTML('beforeend', `
- -
`); - categoryContainerElement.querySelector('button')?.addEventListener('click', doAddFeeCategory); - } - let hasFees = false; - for (const fee of feeCategory.fees) { - // Don't include already applied fees that limit quantity - if (lotOccupancyFeesContainerElement.querySelector(`.container--lotOccupancyFee[data-fee-id='${fee.feeId}'][data-include-quantity='0']`) !== null) { - continue; - } - let includeFee = true; - const feeSearchString = `${feeCategory.feeCategory ?? ''} ${fee.feeName ?? ''} ${fee.feeDescription ?? ''}`.toLowerCase(); - for (const filterStringPiece of filterStringPieces) { - if (!feeSearchString.includes(filterStringPiece)) { - includeFee = false; - break; - } - } - if (!includeFee) { - continue; - } - hasFees = true; - const panelBlockElement = document.createElement(feeCategory.isGroupedFee ? 'div' : 'a'); - panelBlockElement.className = 'panel-block is-block container--fee'; - panelBlockElement.dataset.feeId = fee.feeId.toString(); - panelBlockElement.dataset.feeCategoryId = - feeCategory.feeCategoryId.toString(); - // eslint-disable-next-line no-unsanitized/property - panelBlockElement.innerHTML = `${cityssm.escapeHTML(fee.feeName ?? '')}
- - ${ - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - cityssm - .escapeHTML(fee.feeDescription ?? '') - .replaceAll('\n', '
')} -
`; - if (!feeCategory.isGroupedFee) { - ; - panelBlockElement.href = '#'; - panelBlockElement.addEventListener('click', tryAddFee); - } - ; - categoryContainerElement.querySelector('.panel').append(panelBlockElement); - } - if (hasFees) { - feeFilterResultsElement.append(categoryContainerElement); - } - } - } - cityssm.openHtmlModal('lotOccupancy-addFee', { - onshow(modalElement) { - feeFilterElement = modalElement.querySelector('#feeSelect--feeName'); - feeFilterResultsElement = modalElement.querySelector('#resultsContainer--feeSelect'); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doGetFees`, { - lotOccupancyId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - feeCategories = responseJSON.feeCategories; - feeFilterElement.disabled = false; - feeFilterElement.addEventListener('keyup', filterFees); - feeFilterElement.focus(); - filterFees(); - }); - }, - onshown() { - bulmaJS.toggleHtmlClipped(); - }, - onhidden() { - renderLotOccupancyFees(); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - addFeeButtonElement.focus(); - } - }); - }); - let lotOccupancyTransactions = exports.lotOccupancyTransactions; - delete exports.lotOccupancyTransactions; - const lotOccupancyTransactionsContainerElement = document.querySelector('#container--lotOccupancyTransactions'); - function getTransactionGrandTotal() { - let transactionGrandTotal = 0; - for (const lotOccupancyTransaction of lotOccupancyTransactions) { - transactionGrandTotal += lotOccupancyTransaction.transactionAmount; - } - return transactionGrandTotal; - } - function editLotOccupancyTransaction(clickEvent) { - const transactionIndex = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .transactionIndex ?? '', 10); - const transaction = lotOccupancyTransactions.find((possibleTransaction) => { - return possibleTransaction.transactionIndex === transactionIndex; - }); - let editCloseModalFunction; - function doEdit(formEvent) { - formEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyTransaction`, formEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyTransactions = responseJSON.lotOccupancyTransactions; - renderLotOccupancyTransactions(); - editCloseModalFunction(); - } - else { - bulmaJS.alert({ - title: 'Error Updating Transaction', - message: 'Please try again.', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-editTransaction', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotOccupancyTransactionEdit--lotOccupancyId').value = lotOccupancyId; - modalElement.querySelector('#lotOccupancyTransactionEdit--transactionIndex').value = transaction.transactionIndex?.toString() ?? ''; - modalElement.querySelector('#lotOccupancyTransactionEdit--transactionAmount').value = transaction.transactionAmount.toFixed(2); - modalElement.querySelector('#lotOccupancyTransactionEdit--externalReceiptNumber').value = transaction.externalReceiptNumber ?? ''; - modalElement.querySelector('#lotOccupancyTransactionEdit--transactionNote').value = transaction.transactionNote ?? ''; - modalElement.querySelector('#lotOccupancyTransactionEdit--transactionDateString').value = transaction.transactionDateString ?? ''; - modalElement.querySelector('#lotOccupancyTransactionEdit--transactionTimeString').value = transaction.transactionTimeString ?? ''; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - los.initializeDatePickers(modalElement); - modalElement.querySelector('#lotOccupancyTransactionEdit--transactionAmount').focus(); - modalElement.querySelector('form')?.addEventListener('submit', doEdit); - editCloseModalFunction = closeModalFunction; - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); - } - function deleteLotOccupancyTransaction(clickEvent) { - const transactionIndex = clickEvent.currentTarget.closest('.container--lotOccupancyTransaction').dataset.transactionIndex; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyTransaction`, { - lotOccupancyId, - transactionIndex - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyTransactions = responseJSON.lotOccupancyTransactions; - renderLotOccupancyTransactions(); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Transaction', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: 'Delete Trasnaction', - message: 'Are you sure you want to delete this transaction?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Transaction', - callbackFunction: doDelete - } - }); - } - function renderLotOccupancyTransactions() { - if (lotOccupancyTransactions.length === 0) { - // eslint-disable-next-line no-unsanitized/property - lotOccupancyTransactionsContainerElement.innerHTML = `
-

There are no transactions associated with this record.

-
`; - return; - } - // eslint-disable-next-line no-unsanitized/property - lotOccupancyTransactionsContainerElement.innerHTML = ` - - - - - - - - - - - - -
Date${los.escapedAliases.ExternalReceiptNumber}AmountOptions
Transaction Total
`; - let transactionGrandTotal = 0; - for (const lotOccupancyTransaction of lotOccupancyTransactions) { - transactionGrandTotal += lotOccupancyTransaction.transactionAmount; - const tableRowElement = document.createElement('tr'); - tableRowElement.className = 'container--lotOccupancyTransaction'; - tableRowElement.dataset.transactionIndex = - lotOccupancyTransaction.transactionIndex?.toString(); - let externalReceiptNumberHTML = ''; - if (lotOccupancyTransaction.externalReceiptNumber !== '') { - externalReceiptNumberHTML = cityssm.escapeHTML(lotOccupancyTransaction.externalReceiptNumber ?? ''); - if (los.dynamicsGPIntegrationIsEnabled) { - if (lotOccupancyTransaction.dynamicsGPDocument === undefined) { - externalReceiptNumberHTML += ` - - `; - } - else if (lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(2) === lotOccupancyTransaction.transactionAmount.toFixed(2)) { - externalReceiptNumberHTML += ` - - `; - } - else { - externalReceiptNumberHTML += ` - - `; - } - } - externalReceiptNumberHTML += '
'; - } - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` - ${cityssm.escapeHTML(lotOccupancyTransaction.transactionDateString ?? '')} - - - ${externalReceiptNumberHTML} - ${cityssm.escapeHTML(lotOccupancyTransaction.transactionNote ?? '')} - - - $${cityssm.escapeHTML(lotOccupancyTransaction.transactionAmount.toFixed(2))} - - -
- - -
- `; - tableRowElement - .querySelector('.button--edit') - ?.addEventListener('click', editLotOccupancyTransaction); - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteLotOccupancyTransaction); - lotOccupancyTransactionsContainerElement - .querySelector('tbody') - ?.append(tableRowElement); - } - ; - lotOccupancyTransactionsContainerElement.querySelector('#lotOccupancyTransactions--grandTotal').textContent = `$${transactionGrandTotal.toFixed(2)}`; - const feeGrandTotal = getFeeGrandTotal(); - if (feeGrandTotal.toFixed(2) !== transactionGrandTotal.toFixed(2)) { - lotOccupancyTransactionsContainerElement.insertAdjacentHTML('afterbegin', `
-
-
-
-
Outstanding Balance
-
-
-
- $${cityssm.escapeHTML((feeGrandTotal - transactionGrandTotal).toFixed(2))} -
-
-
-
`); - } - } - const addTransactionButtonElement = document.querySelector('#button--addTransaction'); - addTransactionButtonElement.addEventListener('click', () => { - let transactionAmountElement; - let externalReceiptNumberElement; - let addCloseModalFunction; - function doAddTransaction(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyTransaction`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyTransactions = responseJSON.lotOccupancyTransactions; - addCloseModalFunction(); - renderLotOccupancyTransactions(); - } - else { - bulmaJS.confirm({ - title: 'Error Adding Transaction', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - // eslint-disable-next-line @typescript-eslint/naming-convention - function dynamicsGP_refreshExternalReceiptNumberIcon() { - const externalReceiptNumber = externalReceiptNumberElement.value; - const iconElement = externalReceiptNumberElement - .closest('.control') - ?.querySelector('.icon'); - const helpTextElement = externalReceiptNumberElement - .closest('.field') - ?.querySelector('.help'); - if (externalReceiptNumber === '') { - helpTextElement.innerHTML = ' '; - iconElement.innerHTML = ''; - return; - } - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doGetDynamicsGPDocument`, { - externalReceiptNumber - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (!responseJSON.success || - responseJSON.dynamicsGPDocument === undefined) { - helpTextElement.textContent = 'No Matching Document Found'; - iconElement.innerHTML = - ''; - } - else if (transactionAmountElement.valueAsNumber === - responseJSON.dynamicsGPDocument.documentTotal) { - helpTextElement.textContent = 'Matching Document Found'; - iconElement.innerHTML = - ''; - } - else { - helpTextElement.textContent = `Matching Document: $${responseJSON.dynamicsGPDocument.documentTotal.toFixed(2)}`; - iconElement.innerHTML = - ''; - } - }); - } - cityssm.openHtmlModal('lotOccupancy-addTransaction', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotOccupancyTransactionAdd--lotOccupancyId').value = lotOccupancyId.toString(); - const feeGrandTotal = getFeeGrandTotal(); - const transactionGrandTotal = getTransactionGrandTotal(); - transactionAmountElement = modalElement.querySelector('#lotOccupancyTransactionAdd--transactionAmount'); - transactionAmountElement.min = (-1 * transactionGrandTotal).toFixed(2); - transactionAmountElement.max = Math.max(feeGrandTotal - transactionGrandTotal, 0).toFixed(2); - transactionAmountElement.value = Math.max(feeGrandTotal - transactionGrandTotal, 0).toFixed(2); - if (los.dynamicsGPIntegrationIsEnabled) { - externalReceiptNumberElement = modalElement.querySelector( - // eslint-disable-next-line no-secrets/no-secrets - '#lotOccupancyTransactionAdd--externalReceiptNumber'); - const externalReceiptNumberControlElement = externalReceiptNumberElement.closest('.control'); - externalReceiptNumberControlElement.classList.add('has-icons-right'); - externalReceiptNumberControlElement.insertAdjacentHTML('beforeend', ''); - externalReceiptNumberControlElement.insertAdjacentHTML('afterend', '

'); - externalReceiptNumberElement.addEventListener('change', dynamicsGP_refreshExternalReceiptNumberIcon); - transactionAmountElement.addEventListener('change', dynamicsGP_refreshExternalReceiptNumberIcon); - dynamicsGP_refreshExternalReceiptNumberIcon(); - } - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - transactionAmountElement.focus(); - addCloseModalFunction = closeModalFunction; - modalElement - .querySelector('form') - ?.addEventListener('submit', doAddTransaction); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - addTransactionButtonElement.focus(); - } - }); - }); - renderLotOccupancyFees(); - - } -})(); diff --git a/public-typescript/lotOccupancyEdit/lotOccupancyEdit.js b/public-typescript/lotOccupancyEdit/lotOccupancyEdit.js deleted file mode 100644 index 1bb7557d..00000000 --- a/public-typescript/lotOccupancyEdit/lotOccupancyEdit.js +++ /dev/null @@ -1,481 +0,0 @@ -"use strict"; -/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */ -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -(() => { - const los = exports.los; - const lotOccupancyId = document.querySelector('#lotOccupancy--lotOccupancyId').value; - const isCreate = lotOccupancyId === ''; - /* - * Main form - */ - let refreshAfterSave = isCreate; - function setUnsavedChanges() { - los.setUnsavedChanges(); - document - .querySelector("button[type='submit'][form='form--lotOccupancy']") - ?.classList.remove('is-light'); - } - function clearUnsavedChanges() { - los.clearUnsavedChanges(); - document - .querySelector("button[type='submit'][form='form--lotOccupancy']") - ?.classList.add('is-light'); - } - const formElement = document.querySelector('#form--lotOccupancy'); - formElement.addEventListener('submit', (formEvent) => { - formEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/${isCreate ? 'doCreateLotOccupancy' : 'doUpdateLotOccupancy'}`, formElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - clearUnsavedChanges(); - if (isCreate || refreshAfterSave) { - window.location.href = los.getLotOccupancyURL(responseJSON.lotOccupancyId, true, true); - } - else { - bulmaJS.alert({ - message: `${los.escapedAliases.Occupancy} Updated Successfully`, - contextualColorName: 'success' - }); - } - } - else { - bulmaJS.alert({ - title: `Error Saving ${los.escapedAliases.Occupancy}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - }); - const formInputElements = formElement.querySelectorAll('input, select'); - for (const formInputElement of formInputElements) { - formInputElement.addEventListener('change', setUnsavedChanges); - } - function doCopy() { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doCopyLotOccupancy`, { - lotOccupancyId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - clearUnsavedChanges(); - window.location.href = los.getLotOccupancyURL(responseJSON.lotOccupancyId, true); - } - else { - bulmaJS.alert({ - title: 'Error Copying Record', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - document - .querySelector('#button--copyLotOccupancy') - ?.addEventListener('click', (clickEvent) => { - clickEvent.preventDefault(); - if (los.hasUnsavedChanges()) { - bulmaJS.alert({ - title: 'Unsaved Changes', - message: 'Please save all unsaved changes before continuing.', - contextualColorName: 'warning' - }); - } - else { - bulmaJS.confirm({ - title: `Copy ${los.escapedAliases.Occupancy} Record as New`, - message: 'Are you sure you want to copy this record to a new record?', - contextualColorName: 'info', - okButton: { - text: 'Yes, Copy', - callbackFunction: doCopy - } - }); - } - }); - document - .querySelector('#button--deleteLotOccupancy') - ?.addEventListener('click', (clickEvent) => { - clickEvent.preventDefault(); - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancy`, { - lotOccupancyId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - clearUnsavedChanges(); - window.location.href = los.getLotOccupancyURL(); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Record', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Occupancy} Record`, - message: 'Are you sure you want to delete this record?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete', - callbackFunction: doDelete - } - }); - }); - document - .querySelector('#button--createWorkOrder') - ?.addEventListener('click', (clickEvent) => { - clickEvent.preventDefault(); - let createCloseModalFunction; - function doCreate(formEvent) { - formEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/workOrders/doCreateWorkOrder`, formEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - createCloseModalFunction(); - bulmaJS.confirm({ - title: 'Work Order Created Successfully', - message: 'Would you like to open the work order now?', - contextualColorName: 'success', - okButton: { - text: 'Yes, Open the Work Order', - callbackFunction: () => { - window.location.href = los.getWorkOrderURL(responseJSON.workOrderId, true); - } - } - }); - } - else { - bulmaJS.alert({ - title: 'Error Creating Work Order', - message: responseJSON.errorMessage, - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-createWorkOrder', { - onshow(modalElement) { - ; - modalElement.querySelector('#workOrderCreate--lotOccupancyId').value = lotOccupancyId; - modalElement.querySelector('#workOrderCreate--workOrderOpenDateString').value = cityssm.dateToString(new Date()); - const workOrderTypeSelectElement = modalElement.querySelector('#workOrderCreate--workOrderTypeId'); - const workOrderTypes = exports - .workOrderTypes; - if (workOrderTypes.length === 1) { - workOrderTypeSelectElement.innerHTML = ''; - } - for (const workOrderType of workOrderTypes) { - const optionElement = document.createElement('option'); - optionElement.value = workOrderType.workOrderTypeId.toString(); - optionElement.textContent = workOrderType.workOrderType ?? ''; - workOrderTypeSelectElement.append(optionElement); - } - }, - onshown(modalElement, closeModalFunction) { - createCloseModalFunction = closeModalFunction; - bulmaJS.toggleHtmlClipped(); - modalElement.querySelector('#workOrderCreate--workOrderTypeId').focus(); - modalElement - .querySelector('form') - ?.addEventListener('submit', doCreate); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#button--createWorkOrder').focus(); - } - }); - }); - // Occupancy Type - const occupancyTypeIdElement = document.querySelector('#lotOccupancy--occupancyTypeId'); - if (isCreate) { - const lotOccupancyFieldsContainerElement = document.querySelector('#container--lotOccupancyFields'); - occupancyTypeIdElement.addEventListener('change', () => { - if (occupancyTypeIdElement.value === '') { - // eslint-disable-next-line no-unsanitized/property - lotOccupancyFieldsContainerElement.innerHTML = `
-

Select the ${los.escapedAliases.occupancy} type to load the available fields.

-
`; - return; - } - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doGetOccupancyTypeFields`, { - occupancyTypeId: occupancyTypeIdElement.value - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.occupancyTypeFields.length === 0) { - // eslint-disable-next-line no-unsanitized/property - lotOccupancyFieldsContainerElement.innerHTML = `
-

There are no additional fields for this ${los.escapedAliases.occupancy} type.

-
`; - return; - } - lotOccupancyFieldsContainerElement.innerHTML = ''; - let occupancyTypeFieldIds = ''; - for (const occupancyTypeField of responseJSON.occupancyTypeFields) { - occupancyTypeFieldIds += `,${occupancyTypeField.occupancyTypeFieldId.toString()}`; - const fieldName = `lotOccupancyFieldValue_${occupancyTypeField.occupancyTypeFieldId.toString()}`; - const fieldId = `lotOccupancy--${fieldName}`; - const fieldElement = document.createElement('div'); - fieldElement.className = 'field'; - fieldElement.innerHTML = `
`; - fieldElement.querySelector('label').textContent = occupancyTypeField.occupancyTypeField; - if ((occupancyTypeField.occupancyTypeFieldValues ?? '') === '') { - const inputElement = document.createElement('input'); - inputElement.className = 'input'; - inputElement.id = fieldId; - inputElement.name = fieldName; - inputElement.type = 'text'; - inputElement.required = occupancyTypeField.isRequired; - inputElement.minLength = - occupancyTypeField.minimumLength; - inputElement.maxLength = - occupancyTypeField.maximumLength; - if ((occupancyTypeField.pattern ?? '') !== '') { - inputElement.pattern = occupancyTypeField.pattern; - } - ; - fieldElement.querySelector('.control').append(inputElement); - } - else { - ; - fieldElement.querySelector('.control').innerHTML = `
- -
`; - const selectElement = fieldElement.querySelector('select'); - selectElement.required = occupancyTypeField.isRequired; - const optionValues = occupancyTypeField.occupancyTypeFieldValues.split('\n'); - for (const optionValue of optionValues) { - const optionElement = document.createElement('option'); - optionElement.value = optionValue; - optionElement.textContent = optionValue; - selectElement.append(optionElement); - } - } - console.log(fieldElement); - lotOccupancyFieldsContainerElement.append(fieldElement); - } - lotOccupancyFieldsContainerElement.insertAdjacentHTML('beforeend', - // eslint-disable-next-line no-secrets/no-secrets - ``); - }); - }); - } - else { - const originalOccupancyTypeId = occupancyTypeIdElement.value; - occupancyTypeIdElement.addEventListener('change', () => { - if (occupancyTypeIdElement.value !== originalOccupancyTypeId) { - bulmaJS.confirm({ - title: 'Confirm Change', - message: `Are you sure you want to change the ${los.escapedAliases.occupancy} type?\n - This change affects the additional fields associated with this record, and may also affect the available fees.`, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Keep the Change', - callbackFunction: () => { - refreshAfterSave = true; - } - }, - cancelButton: { - text: 'Revert the Change', - callbackFunction: () => { - occupancyTypeIdElement.value = originalOccupancyTypeId; - } - } - }); - } - }); - } - // Lot Selector - const lotNameElement = document.querySelector('#lotOccupancy--lotName'); - lotNameElement.addEventListener('click', (clickEvent) => { - const currentLotName = clickEvent.currentTarget.value; - let lotSelectCloseModalFunction; - let lotSelectModalElement; - let lotSelectFormElement; - let lotSelectResultsElement; - function renderSelectedLotAndClose(lotId, lotName) { - ; - document.querySelector('#lotOccupancy--lotId').value = lotId.toString(); - document.querySelector('#lotOccupancy--lotName').value = lotName; - setUnsavedChanges(); - lotSelectCloseModalFunction(); - } - function selectExistingLot(clickEvent) { - clickEvent.preventDefault(); - const selectedLotElement = clickEvent.currentTarget; - renderSelectedLotAndClose(selectedLotElement.dataset.lotId ?? '', selectedLotElement.dataset.lotName ?? ''); - } - function searchLots() { - // eslint-disable-next-line no-unsanitized/property - lotSelectResultsElement.innerHTML = - los.getLoadingParagraphHTML('Searching...'); - cityssm.postJSON(`${los.urlPrefix}/lots/doSearchLots`, lotSelectFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.count === 0) { - lotSelectResultsElement.innerHTML = `
-

No results.

-
`; - return; - } - const panelElement = document.createElement('div'); - panelElement.className = 'panel'; - for (const lot of responseJSON.lots) { - const panelBlockElement = document.createElement('a'); - panelBlockElement.className = 'panel-block is-block'; - panelBlockElement.href = '#'; - panelBlockElement.dataset.lotId = lot.lotId.toString(); - panelBlockElement.dataset.lotName = lot.lotName; - // eslint-disable-next-line no-unsanitized/property - panelBlockElement.innerHTML = `
-
- ${cityssm.escapeHTML(lot.lotName ?? '')}
- ${cityssm.escapeHTML(lot.mapName ?? '')} -
-
- ${cityssm.escapeHTML(lot.lotStatus)}
- - ${lot.lotOccupancyCount > 0 ? 'Currently Occupied' : ''} - -
-
`; - panelBlockElement.addEventListener('click', selectExistingLot); - panelElement.append(panelBlockElement); - } - lotSelectResultsElement.innerHTML = ''; - lotSelectResultsElement.append(panelElement); - }); - } - function createLotAndSelect(submitEvent) { - submitEvent.preventDefault(); - const lotName = lotSelectModalElement.querySelector('#lotCreate--lotName').value; - cityssm.postJSON(`${los.urlPrefix}/lots/doCreateLot`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - renderSelectedLotAndClose(responseJSON.lotId ?? '', lotName); - } - else { - bulmaJS.alert({ - title: `Error Creating ${los.escapedAliases.Lot}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-selectLot', { - onshow(modalElement) { - los.populateAliases(modalElement); - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - lotSelectModalElement = modalElement; - lotSelectCloseModalFunction = closeModalFunction; - bulmaJS.init(modalElement); - // search Tab - const lotNameFilterElement = modalElement.querySelector('#lotSelect--lotName'); - if (document.querySelector('#lotOccupancy--lotId') - .value !== '') { - lotNameFilterElement.value = currentLotName; - } - lotNameFilterElement.focus(); - lotNameFilterElement.addEventListener('change', searchLots); - const occupancyStatusFilterElement = modalElement.querySelector('#lotSelect--occupancyStatus'); - occupancyStatusFilterElement.addEventListener('change', searchLots); - if (currentLotName !== '') { - occupancyStatusFilterElement.value = ''; - } - lotSelectFormElement = modalElement.querySelector('#form--lotSelect'); - lotSelectResultsElement = modalElement.querySelector('#resultsContainer--lotSelect'); - lotSelectFormElement.addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault(); - }); - searchLots(); - // Create Tab - if (exports.lotNamePattern) { - const regex = exports.lotNamePattern; - modalElement.querySelector('#lotCreate--lotName').pattern = regex.source; - } - const lotTypeElement = modalElement.querySelector('#lotCreate--lotTypeId'); - for (const lotType of exports.lotTypes) { - const optionElement = document.createElement('option'); - optionElement.value = lotType.lotTypeId.toString(); - optionElement.textContent = lotType.lotType; - lotTypeElement.append(optionElement); - } - const lotStatusElement = modalElement.querySelector('#lotCreate--lotStatusId'); - for (const lotStatus of exports.lotStatuses) { - const optionElement = document.createElement('option'); - optionElement.value = lotStatus.lotStatusId.toString(); - optionElement.textContent = lotStatus.lotStatus; - lotStatusElement.append(optionElement); - } - const mapElement = modalElement.querySelector('#lotCreate--mapId'); - for (const map of exports.maps) { - const optionElement = document.createElement('option'); - optionElement.value = map.mapId.toString(); - optionElement.textContent = - (map.mapName ?? '') === '' ? '(No Name)' : map.mapName ?? ''; - mapElement.append(optionElement); - } - ; - modalElement.querySelector('#form--lotCreate').addEventListener('submit', createLotAndSelect); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); - }); - document - .querySelector('.is-lot-view-button') - ?.addEventListener('click', () => { - const lotId = document.querySelector('#lotOccupancy--lotId').value; - if (lotId === '') { - bulmaJS.alert({ - message: `No ${los.escapedAliases.lot} selected.`, - contextualColorName: 'info' - }); - } - else { - window.open(`${los.urlPrefix}/lots/${lotId}`); - } - }); - document - .querySelector('.is-clear-lot-button') - ?.addEventListener('click', () => { - if (lotNameElement.disabled) { - bulmaJS.alert({ - message: 'You need to unlock the field before clearing it.', - contextualColorName: 'info' - }); - } - else { - lotNameElement.value = `(No ${los.escapedAliases.Lot})`; - document.querySelector('#lotOccupancy--lotId').value = ''; - setUnsavedChanges(); - } - }); - // Start Date - los.initializeDatePickers(formElement); - document - .querySelector('#lotOccupancy--occupancyStartDateString') - ?.addEventListener('change', () => { - const endDatePicker = document.querySelector('#lotOccupancy--occupancyEndDateString').bulmaCalendar.datePicker; - endDatePicker.min = document.querySelector('#lotOccupancy--occupancyStartDateString').value; - endDatePicker.refresh(); - }); - los.initializeUnlockFieldButtons(formElement); - /* - * Occupants - */ - //=include lotOccupancyEditOccupants.js - if (!isCreate) { - //=include lotOccupancyEditComments.js - //=include lotOccupancyEditFees.js - } -})(); diff --git a/public-typescript/lotOccupancyEdit/lotOccupancyEdit.ts b/public-typescript/lotOccupancyEdit/lotOccupancyEdit.ts deleted file mode 100644 index 6b642315..00000000 --- a/public-typescript/lotOccupancyEdit/lotOccupancyEdit.ts +++ /dev/null @@ -1,753 +0,0 @@ -/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */ -/* eslint-disable unicorn/prefer-module */ - -import type { BulmaJS } from '@cityssm/bulma-js/types.js' -import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' - -import type { LOS } from '../../types/globalTypes.js' -import type { - Lot, - LotStatus, - LotType, - MapRecord, - OccupancyTypeField, - WorkOrderType -} from '../../types/recordTypes.js' - -declare const cityssm: cityssmGlobal -declare const bulmaJS: BulmaJS -declare const exports: Record -;(() => { - const los = exports.los as LOS - - const lotOccupancyId = ( - document.querySelector('#lotOccupancy--lotOccupancyId') as HTMLInputElement - ).value - const isCreate = lotOccupancyId === '' - - /* - * Main form - */ - - let refreshAfterSave = isCreate - - function setUnsavedChanges(): void { - los.setUnsavedChanges() - document - .querySelector("button[type='submit'][form='form--lotOccupancy']") - ?.classList.remove('is-light') - } - - function clearUnsavedChanges(): void { - los.clearUnsavedChanges() - document - .querySelector("button[type='submit'][form='form--lotOccupancy']") - ?.classList.add('is-light') - } - - const formElement = document.querySelector( - '#form--lotOccupancy' - ) as HTMLFormElement - - formElement.addEventListener('submit', (formEvent) => { - formEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/${isCreate ? 'doCreateLotOccupancy' : 'doUpdateLotOccupancy'}`, - formElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - lotOccupancyId?: number - errorMessage?: string - } - - if (responseJSON.success) { - clearUnsavedChanges() - - if (isCreate || refreshAfterSave) { - window.location.href = los.getLotOccupancyURL( - responseJSON.lotOccupancyId, - true, - true - ) - } else { - bulmaJS.alert({ - message: `${los.escapedAliases.Occupancy} Updated Successfully`, - contextualColorName: 'success' - }) - } - } else { - bulmaJS.alert({ - title: `Error Saving ${los.escapedAliases.Occupancy}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - }) - - const formInputElements = formElement.querySelectorAll('input, select') - - for (const formInputElement of formInputElements) { - formInputElement.addEventListener('change', setUnsavedChanges) - } - - function doCopy(): void { - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doCopyLotOccupancy`, - { - lotOccupancyId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - lotOccupancyId?: number - } - - if (responseJSON.success) { - clearUnsavedChanges() - - window.location.href = los.getLotOccupancyURL( - responseJSON.lotOccupancyId, - true - ) - } else { - bulmaJS.alert({ - title: 'Error Copying Record', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - document - .querySelector('#button--copyLotOccupancy') - ?.addEventListener('click', (clickEvent) => { - clickEvent.preventDefault() - - if (los.hasUnsavedChanges()) { - bulmaJS.alert({ - title: 'Unsaved Changes', - message: 'Please save all unsaved changes before continuing.', - contextualColorName: 'warning' - }) - } else { - bulmaJS.confirm({ - title: `Copy ${los.escapedAliases.Occupancy} Record as New`, - message: 'Are you sure you want to copy this record to a new record?', - contextualColorName: 'info', - okButton: { - text: 'Yes, Copy', - callbackFunction: doCopy - } - }) - } - }) - - document - .querySelector('#button--deleteLotOccupancy') - ?.addEventListener('click', (clickEvent) => { - clickEvent.preventDefault() - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancy`, - { - lotOccupancyId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - } - - if (responseJSON.success) { - clearUnsavedChanges() - window.location.href = los.getLotOccupancyURL() - } else { - bulmaJS.alert({ - title: 'Error Deleting Record', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Occupancy} Record`, - message: 'Are you sure you want to delete this record?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete', - callbackFunction: doDelete - } - }) - }) - - document - .querySelector('#button--createWorkOrder') - ?.addEventListener('click', (clickEvent) => { - clickEvent.preventDefault() - - let createCloseModalFunction: () => void - - function doCreate(formEvent: SubmitEvent): void { - formEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doCreateWorkOrder`, - formEvent.currentTarget, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - workOrderId?: number - } - - if (responseJSON.success) { - createCloseModalFunction() - - bulmaJS.confirm({ - title: 'Work Order Created Successfully', - message: 'Would you like to open the work order now?', - contextualColorName: 'success', - okButton: { - text: 'Yes, Open the Work Order', - callbackFunction: () => { - window.location.href = los.getWorkOrderURL( - responseJSON.workOrderId, - true - ) - } - } - }) - } else { - bulmaJS.alert({ - title: 'Error Creating Work Order', - message: responseJSON.errorMessage as string, - contextualColorName: 'danger' - }) - } - } - ) - } - - cityssm.openHtmlModal('lotOccupancy-createWorkOrder', { - onshow(modalElement) { - ;( - modalElement.querySelector( - '#workOrderCreate--lotOccupancyId' - ) as HTMLInputElement - ).value = lotOccupancyId - ;( - modalElement.querySelector( - '#workOrderCreate--workOrderOpenDateString' - ) as HTMLInputElement - ).value = cityssm.dateToString(new Date()) - - const workOrderTypeSelectElement = modalElement.querySelector( - '#workOrderCreate--workOrderTypeId' - ) as HTMLSelectElement - - const workOrderTypes = (exports as Record) - .workOrderTypes as WorkOrderType[] - - if (workOrderTypes.length === 1) { - workOrderTypeSelectElement.innerHTML = '' - } - - for (const workOrderType of workOrderTypes) { - const optionElement = document.createElement('option') - optionElement.value = workOrderType.workOrderTypeId.toString() - optionElement.textContent = workOrderType.workOrderType ?? '' - workOrderTypeSelectElement.append(optionElement) - } - }, - onshown(modalElement, closeModalFunction) { - createCloseModalFunction = closeModalFunction - bulmaJS.toggleHtmlClipped() - ;( - modalElement.querySelector( - '#workOrderCreate--workOrderTypeId' - ) as HTMLSelectElement - ).focus() - - modalElement - .querySelector('form') - ?.addEventListener('submit', doCreate) - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - ;( - document.querySelector( - '#button--createWorkOrder' - ) as HTMLButtonElement - ).focus() - } - }) - }) - - // Occupancy Type - - const occupancyTypeIdElement = document.querySelector( - '#lotOccupancy--occupancyTypeId' - ) as HTMLSelectElement - - if (isCreate) { - const lotOccupancyFieldsContainerElement = document.querySelector( - '#container--lotOccupancyFields' - ) as HTMLElement - - occupancyTypeIdElement.addEventListener('change', () => { - if (occupancyTypeIdElement.value === '') { - // eslint-disable-next-line no-unsanitized/property - lotOccupancyFieldsContainerElement.innerHTML = `
-

Select the ${los.escapedAliases.occupancy} type to load the available fields.

-
` - - return - } - - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doGetOccupancyTypeFields`, - { - occupancyTypeId: occupancyTypeIdElement.value - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - occupancyTypeFields: OccupancyTypeField[] - } - - if (responseJSON.occupancyTypeFields.length === 0) { - // eslint-disable-next-line no-unsanitized/property - lotOccupancyFieldsContainerElement.innerHTML = `
-

There are no additional fields for this ${los.escapedAliases.occupancy} type.

-
` - - return - } - - lotOccupancyFieldsContainerElement.innerHTML = '' - - let occupancyTypeFieldIds = '' - - for (const occupancyTypeField of responseJSON.occupancyTypeFields) { - occupancyTypeFieldIds += `,${occupancyTypeField.occupancyTypeFieldId.toString()}` - - const fieldName = `lotOccupancyFieldValue_${occupancyTypeField.occupancyTypeFieldId.toString()}` - - const fieldId = `lotOccupancy--${fieldName}` - - const fieldElement = document.createElement('div') - fieldElement.className = 'field' - fieldElement.innerHTML = `
` - ;( - fieldElement.querySelector('label') as HTMLLabelElement - ).textContent = occupancyTypeField.occupancyTypeField as string - - if ((occupancyTypeField.occupancyTypeFieldValues ?? '') === '') { - const inputElement = document.createElement('input') - - inputElement.className = 'input' - - inputElement.id = fieldId - - inputElement.name = fieldName - - inputElement.type = 'text' - - inputElement.required = occupancyTypeField.isRequired as boolean - inputElement.minLength = - occupancyTypeField.minimumLength as number - inputElement.maxLength = - occupancyTypeField.maximumLength as number - - if ((occupancyTypeField.pattern ?? '') !== '') { - inputElement.pattern = occupancyTypeField.pattern as string - } - - ;(fieldElement.querySelector('.control') as HTMLElement).append( - inputElement - ) - } else { - ;( - fieldElement.querySelector('.control') as HTMLElement - ).innerHTML = `
- -
` - - const selectElement = fieldElement.querySelector( - 'select' - ) as HTMLSelectElement - - selectElement.required = occupancyTypeField.isRequired as boolean - - const optionValues = ( - occupancyTypeField.occupancyTypeFieldValues as string - ).split('\n') - - for (const optionValue of optionValues) { - const optionElement = document.createElement('option') - optionElement.value = optionValue - optionElement.textContent = optionValue - selectElement.append(optionElement) - } - } - - console.log(fieldElement) - - lotOccupancyFieldsContainerElement.append(fieldElement) - } - - lotOccupancyFieldsContainerElement.insertAdjacentHTML( - 'beforeend', - // eslint-disable-next-line no-secrets/no-secrets - `` - ) - } - ) - }) - } else { - const originalOccupancyTypeId = occupancyTypeIdElement.value - - occupancyTypeIdElement.addEventListener('change', () => { - if (occupancyTypeIdElement.value !== originalOccupancyTypeId) { - bulmaJS.confirm({ - title: 'Confirm Change', - message: `Are you sure you want to change the ${los.escapedAliases.occupancy} type?\n - This change affects the additional fields associated with this record, and may also affect the available fees.`, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Keep the Change', - callbackFunction: () => { - refreshAfterSave = true - } - }, - cancelButton: { - text: 'Revert the Change', - callbackFunction: () => { - occupancyTypeIdElement.value = originalOccupancyTypeId - } - } - }) - } - }) - } - - // Lot Selector - - const lotNameElement = document.querySelector( - '#lotOccupancy--lotName' - ) as HTMLInputElement - - lotNameElement.addEventListener('click', (clickEvent) => { - const currentLotName = (clickEvent.currentTarget as HTMLInputElement).value - - let lotSelectCloseModalFunction: () => void - let lotSelectModalElement: HTMLElement - - let lotSelectFormElement: HTMLFormElement - let lotSelectResultsElement: HTMLElement - - function renderSelectedLotAndClose( - lotId: number | string, - lotName: string - ): void { - ;( - document.querySelector('#lotOccupancy--lotId') as HTMLInputElement - ).value = lotId.toString() - ;( - document.querySelector('#lotOccupancy--lotName') as HTMLInputElement - ).value = lotName - - setUnsavedChanges() - lotSelectCloseModalFunction() - } - - function selectExistingLot(clickEvent: Event): void { - clickEvent.preventDefault() - - const selectedLotElement = clickEvent.currentTarget as HTMLElement - - renderSelectedLotAndClose( - selectedLotElement.dataset.lotId ?? '', - selectedLotElement.dataset.lotName ?? '' - ) - } - - function searchLots(): void { - // eslint-disable-next-line no-unsanitized/property - lotSelectResultsElement.innerHTML = - los.getLoadingParagraphHTML('Searching...') - - cityssm.postJSON( - `${los.urlPrefix}/lots/doSearchLots`, - lotSelectFormElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - count: number - lots: Lot[] - } - - if (responseJSON.count === 0) { - lotSelectResultsElement.innerHTML = `
-

No results.

-
` - - return - } - - const panelElement = document.createElement('div') - panelElement.className = 'panel' - - for (const lot of responseJSON.lots) { - const panelBlockElement = document.createElement('a') - panelBlockElement.className = 'panel-block is-block' - panelBlockElement.href = '#' - - panelBlockElement.dataset.lotId = lot.lotId.toString() - panelBlockElement.dataset.lotName = lot.lotName - - // eslint-disable-next-line no-unsanitized/property - panelBlockElement.innerHTML = `
-
- ${cityssm.escapeHTML(lot.lotName ?? '')}
- ${cityssm.escapeHTML(lot.mapName ?? '')} -
-
- ${cityssm.escapeHTML(lot.lotStatus as string)}
- - ${lot.lotOccupancyCount! > 0 ? 'Currently Occupied' : ''} - -
-
` - - panelBlockElement.addEventListener('click', selectExistingLot) - - panelElement.append(panelBlockElement) - } - - lotSelectResultsElement.innerHTML = '' - lotSelectResultsElement.append(panelElement) - } - ) - } - - function createLotAndSelect(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - - const lotName = ( - lotSelectModalElement.querySelector( - '#lotCreate--lotName' - ) as HTMLInputElement - ).value - - cityssm.postJSON( - `${los.urlPrefix}/lots/doCreateLot`, - submitEvent.currentTarget, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - lotId?: number - } - - if (responseJSON.success) { - renderSelectedLotAndClose(responseJSON.lotId ?? '', lotName) - } else { - bulmaJS.alert({ - title: `Error Creating ${los.escapedAliases.Lot}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - cityssm.openHtmlModal('lotOccupancy-selectLot', { - onshow(modalElement) { - los.populateAliases(modalElement) - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped() - - lotSelectModalElement = modalElement - lotSelectCloseModalFunction = closeModalFunction - - bulmaJS.init(modalElement) - - // search Tab - - const lotNameFilterElement = modalElement.querySelector( - '#lotSelect--lotName' - ) as HTMLInputElement - - if ( - (document.querySelector('#lotOccupancy--lotId') as HTMLInputElement) - .value !== '' - ) { - lotNameFilterElement.value = currentLotName - } - - lotNameFilterElement.focus() - lotNameFilterElement.addEventListener('change', searchLots) - - const occupancyStatusFilterElement = modalElement.querySelector( - '#lotSelect--occupancyStatus' - ) as HTMLSelectElement - occupancyStatusFilterElement.addEventListener('change', searchLots) - - if (currentLotName !== '') { - occupancyStatusFilterElement.value = '' - } - - lotSelectFormElement = modalElement.querySelector( - '#form--lotSelect' - ) as HTMLFormElement - lotSelectResultsElement = modalElement.querySelector( - '#resultsContainer--lotSelect' - ) as HTMLElement - - lotSelectFormElement.addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault() - }) - - searchLots() - - // Create Tab - - if (exports.lotNamePattern) { - const regex = exports.lotNamePattern as RegExp - - ;( - modalElement.querySelector( - '#lotCreate--lotName' - ) as HTMLInputElement - ).pattern = regex.source - } - - const lotTypeElement = modalElement.querySelector( - '#lotCreate--lotTypeId' - ) as HTMLSelectElement - - for (const lotType of exports.lotTypes as LotType[]) { - const optionElement = document.createElement('option') - optionElement.value = lotType.lotTypeId.toString() - optionElement.textContent = lotType.lotType - lotTypeElement.append(optionElement) - } - - const lotStatusElement = modalElement.querySelector( - '#lotCreate--lotStatusId' - ) as HTMLSelectElement - - for (const lotStatus of exports.lotStatuses as LotStatus[]) { - const optionElement = document.createElement('option') - optionElement.value = lotStatus.lotStatusId.toString() - optionElement.textContent = lotStatus.lotStatus - lotStatusElement.append(optionElement) - } - - const mapElement = modalElement.querySelector( - '#lotCreate--mapId' - ) as HTMLSelectElement - - for (const map of exports.maps as MapRecord[]) { - const optionElement = document.createElement('option') - optionElement.value = map.mapId!.toString() - optionElement.textContent = - (map.mapName ?? '') === '' ? '(No Name)' : map.mapName ?? '' - mapElement.append(optionElement) - } - - ;( - modalElement.querySelector('#form--lotCreate') as HTMLFormElement - ).addEventListener('submit', createLotAndSelect) - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - } - }) - }) - - document - .querySelector('.is-lot-view-button') - ?.addEventListener('click', () => { - const lotId = ( - document.querySelector('#lotOccupancy--lotId') as HTMLInputElement - ).value - - if (lotId === '') { - bulmaJS.alert({ - message: `No ${los.escapedAliases.lot} selected.`, - contextualColorName: 'info' - }) - } else { - window.open(`${los.urlPrefix}/lots/${lotId}`) - } - }) - - document - .querySelector('.is-clear-lot-button') - ?.addEventListener('click', () => { - if (lotNameElement.disabled) { - bulmaJS.alert({ - message: 'You need to unlock the field before clearing it.', - contextualColorName: 'info' - }) - } else { - lotNameElement.value = `(No ${los.escapedAliases.Lot})` - ;( - document.querySelector('#lotOccupancy--lotId') as HTMLInputElement - ).value = '' - - setUnsavedChanges() - } - }) - - // Start Date - - los.initializeDatePickers(formElement) - - document - .querySelector('#lotOccupancy--occupancyStartDateString') - ?.addEventListener('change', () => { - const endDatePicker = ( - document.querySelector( - '#lotOccupancy--occupancyEndDateString' - ) as HTMLInputElement - ).bulmaCalendar.datePicker - - endDatePicker.min = ( - document.querySelector( - '#lotOccupancy--occupancyStartDateString' - ) as HTMLInputElement - ).value - - endDatePicker.refresh() - }) - - los.initializeUnlockFieldButtons(formElement) - - /* - * Occupants - */ - - //=include lotOccupancyEditOccupants.js - - if (!isCreate) { - //=include lotOccupancyEditComments.js - //=include lotOccupancyEditFees.js - } -})() diff --git a/public-typescript/lotOccupancyEdit/lotOccupancyEditComments.d.ts b/public-typescript/lotOccupancyEdit/lotOccupancyEditComments.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/public-typescript/lotOccupancyEdit/lotOccupancyEditComments.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/public-typescript/lotOccupancyEdit/lotOccupancyEditComments.js b/public-typescript/lotOccupancyEdit/lotOccupancyEditComments.js deleted file mode 100644 index b4c5d1bd..00000000 --- a/public-typescript/lotOccupancyEdit/lotOccupancyEditComments.js +++ /dev/null @@ -1,185 +0,0 @@ -"use strict"; -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -let lotOccupancyComments = exports.lotOccupancyComments; -delete exports.lotOccupancyComments; -function openEditLotOccupancyComment(clickEvent) { - const lotOccupancyCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .lotOccupancyCommentId ?? '', 10); - const lotOccupancyComment = lotOccupancyComments.find((currentLotOccupancyComment) => { - return (currentLotOccupancyComment.lotOccupancyCommentId === - lotOccupancyCommentId); - }); - let editFormElement; - let editCloseModalFunction; - function editComment(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyComment`, editFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyComments = responseJSON.lotOccupancyComments ?? []; - editCloseModalFunction(); - renderLotOccupancyComments(); - } - else { - bulmaJS.alert({ - title: 'Error Updating Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-editComment', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyId').value = lotOccupancyId; - modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyCommentId').value = lotOccupancyCommentId.toString(); - modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyComment').value = lotOccupancyComment.lotOccupancyComment ?? ''; - const lotOccupancyCommentDateStringElement = modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyCommentDateString'); - lotOccupancyCommentDateStringElement.value = - lotOccupancyComment.lotOccupancyCommentDateString ?? ''; - const currentDateString = cityssm.dateToString(new Date()); - lotOccupancyCommentDateStringElement.max = - lotOccupancyComment.lotOccupancyCommentDateString <= currentDateString - ? currentDateString - : lotOccupancyComment.lotOccupancyCommentDateString ?? ''; - modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyCommentTimeString').value = lotOccupancyComment.lotOccupancyCommentTimeString ?? ''; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - los.initializeDatePickers(modalElement); - modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyComment').focus(); - editFormElement = modalElement.querySelector('form'); - editFormElement.addEventListener('submit', editComment); - editCloseModalFunction = closeModalFunction; - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); -} -function deleteLotOccupancyComment(clickEvent) { - const lotOccupancyCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .lotOccupancyCommentId ?? '', 10); - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyComment`, { - lotOccupancyId, - lotOccupancyCommentId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyComments = responseJSON.lotOccupancyComments; - renderLotOccupancyComments(); - } - else { - bulmaJS.alert({ - title: 'Error Removing Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: 'Remove Comment?', - message: 'Are you sure you want to remove this comment?', - okButton: { - text: 'Yes, Remove Comment', - callbackFunction: doDelete - }, - contextualColorName: 'warning' - }); -} -function renderLotOccupancyComments() { - const containerElement = document.querySelector('#container--lotOccupancyComments'); - if (lotOccupancyComments.length === 0) { - containerElement.innerHTML = `
-

There are no comments associated with this record.

-
`; - return; - } - const tableElement = document.createElement('table'); - tableElement.className = 'table is-fullwidth is-striped is-hoverable'; - tableElement.innerHTML = ` - Commentor - Comment Date - Comment - Options - - `; - for (const lotOccupancyComment of lotOccupancyComments) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.lotOccupancyCommentId = - lotOccupancyComment.lotOccupancyCommentId?.toString(); - tableRowElement.innerHTML = `${cityssm.escapeHTML(lotOccupancyComment.recordCreate_userName ?? '')} - - ${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyCommentDateString ?? '')} - ${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyCommentTime === 0 - ? '' - : lotOccupancyComment.lotOccupancyCommentTimePeriodString ?? '')} - - ${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyComment ?? '')} - -
- - -
- `; - tableRowElement - .querySelector('.button--edit') - ?.addEventListener('click', openEditLotOccupancyComment); - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteLotOccupancyComment); - tableElement.querySelector('tbody')?.append(tableRowElement); - } - containerElement.innerHTML = ''; - containerElement.append(tableElement); -} -document.querySelector('#button--addComment')?.addEventListener('click', () => { - let addFormElement; - let addCloseModalFunction; - function addComment(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyComment`, addFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyComments = responseJSON.lotOccupancyComments; - addCloseModalFunction(); - renderLotOccupancyComments(); - } - else { - bulmaJS.alert({ - title: 'Error Adding Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-addComment', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotOccupancyCommentAdd--lotOccupancyId').value = lotOccupancyId; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - modalElement.querySelector('#lotOccupancyCommentAdd--lotOccupancyComment').focus(); - addFormElement = modalElement.querySelector('form'); - addFormElement.addEventListener('submit', addComment); - addCloseModalFunction = closeModalFunction; - }, - onremoved: () => { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#button--addComment').focus(); - } - }); -}); -renderLotOccupancyComments(); diff --git a/public-typescript/lotOccupancyEdit/lotOccupancyEditComments.ts b/public-typescript/lotOccupancyEdit/lotOccupancyEditComments.ts deleted file mode 100644 index aeaefc2e..00000000 --- a/public-typescript/lotOccupancyEdit/lotOccupancyEditComments.ts +++ /dev/null @@ -1,305 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ - -import type { BulmaJS } from '@cityssm/bulma-js/types.js' -import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' - -import type { LOS } from '../../types/globalTypes.js' -import type { LotOccupancyComment } from '../../types/recordTypes.js' - -declare const cityssm: cityssmGlobal -declare const bulmaJS: BulmaJS - -declare const los: LOS - -declare const lotOccupancyId: string - -declare const exports: Record - -let lotOccupancyComments = exports.lotOccupancyComments as LotOccupancyComment[] -delete exports.lotOccupancyComments - -function openEditLotOccupancyComment(clickEvent: Event): void { - const lotOccupancyCommentId = Number.parseInt( - (clickEvent.currentTarget as HTMLElement).closest('tr')?.dataset - .lotOccupancyCommentId ?? '', - 10 - ) - - const lotOccupancyComment = lotOccupancyComments.find( - (currentLotOccupancyComment) => { - return ( - currentLotOccupancyComment.lotOccupancyCommentId === - lotOccupancyCommentId - ) - } - ) as LotOccupancyComment - - let editFormElement: HTMLFormElement - let editCloseModalFunction: () => void - - function editComment(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyComment`, - editFormElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - lotOccupancyComments?: LotOccupancyComment[] - } - - if (responseJSON.success) { - lotOccupancyComments = responseJSON.lotOccupancyComments ?? [] - editCloseModalFunction() - renderLotOccupancyComments() - } else { - bulmaJS.alert({ - title: 'Error Updating Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - cityssm.openHtmlModal('lotOccupancy-editComment', { - onshow(modalElement) { - los.populateAliases(modalElement) - ;( - modalElement.querySelector( - '#lotOccupancyCommentEdit--lotOccupancyId' - ) as HTMLInputElement - ).value = lotOccupancyId - ;( - modalElement.querySelector( - '#lotOccupancyCommentEdit--lotOccupancyCommentId' - ) as HTMLInputElement - ).value = lotOccupancyCommentId.toString() - ;( - modalElement.querySelector( - '#lotOccupancyCommentEdit--lotOccupancyComment' - ) as HTMLInputElement - ).value = lotOccupancyComment.lotOccupancyComment ?? '' - - const lotOccupancyCommentDateStringElement = modalElement.querySelector( - '#lotOccupancyCommentEdit--lotOccupancyCommentDateString' - ) as HTMLInputElement - - lotOccupancyCommentDateStringElement.value = - lotOccupancyComment.lotOccupancyCommentDateString ?? '' - - const currentDateString = cityssm.dateToString(new Date()) - - lotOccupancyCommentDateStringElement.max = - lotOccupancyComment.lotOccupancyCommentDateString! <= currentDateString - ? currentDateString - : lotOccupancyComment.lotOccupancyCommentDateString ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyCommentEdit--lotOccupancyCommentTimeString' - ) as HTMLInputElement - ).value = lotOccupancyComment.lotOccupancyCommentTimeString ?? '' - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped() - - los.initializeDatePickers(modalElement) - ;( - modalElement.querySelector( - '#lotOccupancyCommentEdit--lotOccupancyComment' - ) as HTMLTextAreaElement - ).focus() - - editFormElement = modalElement.querySelector('form') as HTMLFormElement - - editFormElement.addEventListener('submit', editComment) - - editCloseModalFunction = closeModalFunction - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - } - }) -} - -function deleteLotOccupancyComment(clickEvent: Event): void { - const lotOccupancyCommentId = Number.parseInt( - (clickEvent.currentTarget as HTMLElement).closest('tr')?.dataset - .lotOccupancyCommentId ?? '', - 10 - ) - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyComment`, - { - lotOccupancyId, - lotOccupancyCommentId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - lotOccupancyComments: LotOccupancyComment[] - } - - if (responseJSON.success) { - lotOccupancyComments = responseJSON.lotOccupancyComments - renderLotOccupancyComments() - } else { - bulmaJS.alert({ - title: 'Error Removing Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - bulmaJS.confirm({ - title: 'Remove Comment?', - message: 'Are you sure you want to remove this comment?', - okButton: { - text: 'Yes, Remove Comment', - callbackFunction: doDelete - }, - contextualColorName: 'warning' - }) -} - -function renderLotOccupancyComments(): void { - const containerElement = document.querySelector( - '#container--lotOccupancyComments' - ) as HTMLElement - - if (lotOccupancyComments.length === 0) { - containerElement.innerHTML = `
-

There are no comments associated with this record.

-
` - return - } - - const tableElement = document.createElement('table') - tableElement.className = 'table is-fullwidth is-striped is-hoverable' - tableElement.innerHTML = ` - Commentor - Comment Date - Comment - Options - - ` - - for (const lotOccupancyComment of lotOccupancyComments) { - const tableRowElement = document.createElement('tr') - tableRowElement.dataset.lotOccupancyCommentId = - lotOccupancyComment.lotOccupancyCommentId?.toString() - - tableRowElement.innerHTML = `${cityssm.escapeHTML(lotOccupancyComment.recordCreate_userName ?? '')} - - ${cityssm.escapeHTML( - lotOccupancyComment.lotOccupancyCommentDateString ?? '' - )} - ${cityssm.escapeHTML( - lotOccupancyComment.lotOccupancyCommentTime === 0 - ? '' - : lotOccupancyComment.lotOccupancyCommentTimePeriodString ?? '' - )} - - ${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyComment ?? '')} - -
- - -
- ` - - tableRowElement - .querySelector('.button--edit') - ?.addEventListener('click', openEditLotOccupancyComment) - - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteLotOccupancyComment) - - tableElement.querySelector('tbody')?.append(tableRowElement) - } - - containerElement.innerHTML = '' - containerElement.append(tableElement) -} - -document.querySelector('#button--addComment')?.addEventListener('click', () => { - let addFormElement: HTMLFormElement - let addCloseModalFunction: () => void - - function addComment(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doAddLotOccupancyComment`, - addFormElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - lotOccupancyComments: LotOccupancyComment[] - } - - if (responseJSON.success) { - lotOccupancyComments = responseJSON.lotOccupancyComments - addCloseModalFunction() - renderLotOccupancyComments() - } else { - bulmaJS.alert({ - title: 'Error Adding Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - cityssm.openHtmlModal('lotOccupancy-addComment', { - onshow(modalElement) { - los.populateAliases(modalElement) - ;( - modalElement.querySelector( - '#lotOccupancyCommentAdd--lotOccupancyId' - ) as HTMLInputElement - ).value = lotOccupancyId - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped() - ;( - modalElement.querySelector( - '#lotOccupancyCommentAdd--lotOccupancyComment' - ) as HTMLTextAreaElement - ).focus() - - addFormElement = modalElement.querySelector('form') as HTMLFormElement - - addFormElement.addEventListener('submit', addComment) - - addCloseModalFunction = closeModalFunction - }, - onremoved: () => { - bulmaJS.toggleHtmlClipped() - ;( - document.querySelector('#button--addComment') as HTMLButtonElement - ).focus() - } - }) -}) - -renderLotOccupancyComments() diff --git a/public-typescript/lotOccupancyEdit/lotOccupancyEditFees.d.ts b/public-typescript/lotOccupancyEdit/lotOccupancyEditFees.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/public-typescript/lotOccupancyEdit/lotOccupancyEditFees.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/public-typescript/lotOccupancyEdit/lotOccupancyEditFees.js b/public-typescript/lotOccupancyEdit/lotOccupancyEditFees.js deleted file mode 100644 index 61a2dc03..00000000 --- a/public-typescript/lotOccupancyEdit/lotOccupancyEditFees.js +++ /dev/null @@ -1,671 +0,0 @@ -"use strict"; -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -let lotOccupancyFees = exports.lotOccupancyFees; -delete exports.lotOccupancyFees; -const lotOccupancyFeesContainerElement = document.querySelector('#container--lotOccupancyFees'); -function getFeeGrandTotal() { - let feeGrandTotal = 0; - for (const lotOccupancyFee of lotOccupancyFees) { - feeGrandTotal += - ((lotOccupancyFee.feeAmount ?? 0) + (lotOccupancyFee.taxAmount ?? 0)) * - (lotOccupancyFee.quantity ?? 0); - } - return feeGrandTotal; -} -function editLotOccupancyFeeQuantity(clickEvent) { - const feeId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .feeId ?? '', 10); - const fee = lotOccupancyFees.find((possibleFee) => { - return possibleFee.feeId === feeId; - }); - let updateCloseModalFunction; - function doUpdateQuantity(formEvent) { - formEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyFeeQuantity`, formEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyFees = responseJSON.lotOccupancyFees; - renderLotOccupancyFees(); - updateCloseModalFunction(); - } - else { - bulmaJS.alert({ - title: 'Error Updating Quantity', - message: 'Please try again.', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-editFeeQuantity', { - onshow(modalElement) { - ; - modalElement.querySelector('#lotOccupancyFeeQuantity--lotOccupancyId').value = lotOccupancyId; - modalElement.querySelector('#lotOccupancyFeeQuantity--feeId').value = fee.feeId.toString(); - modalElement.querySelector('#lotOccupancyFeeQuantity--quantity').valueAsNumber = fee.quantity ?? 0; - modalElement.querySelector('#lotOccupancyFeeQuantity--quantityUnit').textContent = fee.quantityUnit ?? ''; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - updateCloseModalFunction = closeModalFunction; - modalElement.querySelector('#lotOccupancyFeeQuantity--quantity').focus(); - modalElement - .querySelector('form') - ?.addEventListener('submit', doUpdateQuantity); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); -} -function deleteLotOccupancyFee(clickEvent) { - const feeId = clickEvent.currentTarget.closest('.container--lotOccupancyFee').dataset.feeId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyFee`, { - lotOccupancyId, - feeId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyFees = responseJSON.lotOccupancyFees; - renderLotOccupancyFees(); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Fee', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: 'Delete Fee', - message: 'Are you sure you want to delete this fee?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Fee', - callbackFunction: doDelete - } - }); -} -function renderLotOccupancyFees() { - if (lotOccupancyFees.length === 0) { - lotOccupancyFeesContainerElement.innerHTML = `
-

There are no fees associated with this record.

-
`; - renderLotOccupancyTransactions(); - return; - } - // eslint-disable-next-line no-secrets/no-secrets - lotOccupancyFeesContainerElement.innerHTML = ` - - - - - - - - - - - - - - - - - - - - - - -
FeeUnit Cost×QuantityequalsTotalOptions
Subtotal
Tax
Grand Total
`; - let feeAmountTotal = 0; - let taxAmountTotal = 0; - for (const lotOccupancyFee of lotOccupancyFees) { - const tableRowElement = document.createElement('tr'); - tableRowElement.className = 'container--lotOccupancyFee'; - tableRowElement.dataset.feeId = lotOccupancyFee.feeId.toString(); - tableRowElement.dataset.includeQuantity = - lotOccupancyFee.includeQuantity ?? false ? '1' : '0'; - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` - ${cityssm.escapeHTML(lotOccupancyFee.feeName ?? '')}
- ${cityssm.escapeHTML(lotOccupancyFee.feeCategory ?? '')} - - ${lotOccupancyFee.quantity === 1 - ? '' - : ` - $${lotOccupancyFee.feeAmount?.toFixed(2)} - - × - ${lotOccupancyFee.quantity?.toString()} - =`} - - $${((lotOccupancyFee.feeAmount ?? 0) * (lotOccupancyFee.quantity ?? 0)).toFixed(2)} - - -
- ${lotOccupancyFee.includeQuantity ?? false - ? `` - : ''} - -
- `; - tableRowElement - .querySelector('.button--editQuantity') - ?.addEventListener('click', editLotOccupancyFeeQuantity); - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteLotOccupancyFee); - lotOccupancyFeesContainerElement - .querySelector('tbody') - ?.append(tableRowElement); - feeAmountTotal += - (lotOccupancyFee.feeAmount ?? 0) * (lotOccupancyFee.quantity ?? 0); - taxAmountTotal += - (lotOccupancyFee.taxAmount ?? 0) * (lotOccupancyFee.quantity ?? 0); - } - ; - lotOccupancyFeesContainerElement.querySelector('#lotOccupancyFees--feeAmountTotal').textContent = `$${feeAmountTotal.toFixed(2)}`; - lotOccupancyFeesContainerElement.querySelector('#lotOccupancyFees--taxAmountTotal').textContent = `$${taxAmountTotal.toFixed(2)}`; - lotOccupancyFeesContainerElement.querySelector('#lotOccupancyFees--grandTotal').textContent = `$${(feeAmountTotal + taxAmountTotal).toFixed(2)}`; - renderLotOccupancyTransactions(); -} -const addFeeButtonElement = document.querySelector('#button--addFee'); -addFeeButtonElement.addEventListener('click', () => { - if (los.hasUnsavedChanges()) { - bulmaJS.alert({ - message: 'Please save all unsaved changes before adding fees.', - contextualColorName: 'warning' - }); - return; - } - let feeCategories; - let feeFilterElement; - let feeFilterResultsElement; - function doAddFeeCategory(clickEvent) { - clickEvent.preventDefault(); - const feeCategoryId = Number.parseInt(clickEvent.currentTarget.dataset.feeCategoryId ?? '', 10); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyFeeCategory`, { - lotOccupancyId, - feeCategoryId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyFees = responseJSON.lotOccupancyFees; - renderLotOccupancyFees(); - bulmaJS.alert({ - message: 'Fee Group Added Successfully', - contextualColorName: 'success' - }); - } - else { - bulmaJS.alert({ - title: 'Error Adding Fee', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function doAddFee(feeId, quantity = 1) { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyFee`, { - lotOccupancyId, - feeId, - quantity - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyFees = responseJSON.lotOccupancyFees; - renderLotOccupancyFees(); - filterFees(); - } - else { - bulmaJS.alert({ - title: 'Error Adding Fee', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function doSetQuantityAndAddFee(fee) { - let quantityElement; - let quantityCloseModalFunction; - function doSetQuantity(submitEvent) { - submitEvent.preventDefault(); - doAddFee(fee.feeId, quantityElement.value); - quantityCloseModalFunction(); - } - cityssm.openHtmlModal('lotOccupancy-setFeeQuantity', { - onshow(modalElement) { - ; - modalElement.querySelector('#lotOccupancyFeeQuantity--quantityUnit').textContent = fee.quantityUnit ?? ''; - }, - onshown(modalElement, closeModalFunction) { - quantityCloseModalFunction = closeModalFunction; - quantityElement = modalElement.querySelector('#lotOccupancyFeeQuantity--quantity'); - modalElement - .querySelector('form') - ?.addEventListener('submit', doSetQuantity); - } - }); - } - function tryAddFee(clickEvent) { - clickEvent.preventDefault(); - const feeId = Number.parseInt(clickEvent.currentTarget.dataset.feeId ?? '', 10); - const feeCategoryId = Number.parseInt(clickEvent.currentTarget.dataset.feeCategoryId ?? '', 10); - const feeCategory = feeCategories.find((currentFeeCategory) => { - return currentFeeCategory.feeCategoryId === feeCategoryId; - }); - const fee = feeCategory.fees.find((currentFee) => { - return currentFee.feeId === feeId; - }); - if (fee.includeQuantity ?? false) { - doSetQuantityAndAddFee(fee); - } - else { - doAddFee(feeId); - } - } - function filterFees() { - const filterStringPieces = feeFilterElement.value - .trim() - .toLowerCase() - .split(' '); - feeFilterResultsElement.innerHTML = ''; - for (const feeCategory of feeCategories) { - const categoryContainerElement = document.createElement('div'); - categoryContainerElement.className = 'container--feeCategory'; - categoryContainerElement.dataset.feeCategoryId = - feeCategory.feeCategoryId.toString(); - categoryContainerElement.innerHTML = `
-
-

- ${cityssm.escapeHTML(feeCategory.feeCategory ?? '')} -

-
-
-
`; - if (feeCategory.isGroupedFee) { - // eslint-disable-next-line no-unsanitized/method - categoryContainerElement.querySelector('.columns')?.insertAdjacentHTML('beforeend', `
- -
`); - categoryContainerElement.querySelector('button')?.addEventListener('click', doAddFeeCategory); - } - let hasFees = false; - for (const fee of feeCategory.fees) { - // Don't include already applied fees that limit quantity - if (lotOccupancyFeesContainerElement.querySelector(`.container--lotOccupancyFee[data-fee-id='${fee.feeId}'][data-include-quantity='0']`) !== null) { - continue; - } - let includeFee = true; - const feeSearchString = `${feeCategory.feeCategory ?? ''} ${fee.feeName ?? ''} ${fee.feeDescription ?? ''}`.toLowerCase(); - for (const filterStringPiece of filterStringPieces) { - if (!feeSearchString.includes(filterStringPiece)) { - includeFee = false; - break; - } - } - if (!includeFee) { - continue; - } - hasFees = true; - const panelBlockElement = document.createElement(feeCategory.isGroupedFee ? 'div' : 'a'); - panelBlockElement.className = 'panel-block is-block container--fee'; - panelBlockElement.dataset.feeId = fee.feeId.toString(); - panelBlockElement.dataset.feeCategoryId = - feeCategory.feeCategoryId.toString(); - // eslint-disable-next-line no-unsanitized/property - panelBlockElement.innerHTML = `${cityssm.escapeHTML(fee.feeName ?? '')}
- - ${ - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - cityssm - .escapeHTML(fee.feeDescription ?? '') - .replaceAll('\n', '
')} -
`; - if (!feeCategory.isGroupedFee) { - ; - panelBlockElement.href = '#'; - panelBlockElement.addEventListener('click', tryAddFee); - } - ; - categoryContainerElement.querySelector('.panel').append(panelBlockElement); - } - if (hasFees) { - feeFilterResultsElement.append(categoryContainerElement); - } - } - } - cityssm.openHtmlModal('lotOccupancy-addFee', { - onshow(modalElement) { - feeFilterElement = modalElement.querySelector('#feeSelect--feeName'); - feeFilterResultsElement = modalElement.querySelector('#resultsContainer--feeSelect'); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doGetFees`, { - lotOccupancyId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - feeCategories = responseJSON.feeCategories; - feeFilterElement.disabled = false; - feeFilterElement.addEventListener('keyup', filterFees); - feeFilterElement.focus(); - filterFees(); - }); - }, - onshown() { - bulmaJS.toggleHtmlClipped(); - }, - onhidden() { - renderLotOccupancyFees(); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - addFeeButtonElement.focus(); - } - }); -}); -let lotOccupancyTransactions = exports.lotOccupancyTransactions; -delete exports.lotOccupancyTransactions; -const lotOccupancyTransactionsContainerElement = document.querySelector('#container--lotOccupancyTransactions'); -function getTransactionGrandTotal() { - let transactionGrandTotal = 0; - for (const lotOccupancyTransaction of lotOccupancyTransactions) { - transactionGrandTotal += lotOccupancyTransaction.transactionAmount; - } - return transactionGrandTotal; -} -function editLotOccupancyTransaction(clickEvent) { - const transactionIndex = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .transactionIndex ?? '', 10); - const transaction = lotOccupancyTransactions.find((possibleTransaction) => { - return possibleTransaction.transactionIndex === transactionIndex; - }); - let editCloseModalFunction; - function doEdit(formEvent) { - formEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyTransaction`, formEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyTransactions = responseJSON.lotOccupancyTransactions; - renderLotOccupancyTransactions(); - editCloseModalFunction(); - } - else { - bulmaJS.alert({ - title: 'Error Updating Transaction', - message: 'Please try again.', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-editTransaction', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotOccupancyTransactionEdit--lotOccupancyId').value = lotOccupancyId; - modalElement.querySelector('#lotOccupancyTransactionEdit--transactionIndex').value = transaction.transactionIndex?.toString() ?? ''; - modalElement.querySelector('#lotOccupancyTransactionEdit--transactionAmount').value = transaction.transactionAmount.toFixed(2); - modalElement.querySelector('#lotOccupancyTransactionEdit--externalReceiptNumber').value = transaction.externalReceiptNumber ?? ''; - modalElement.querySelector('#lotOccupancyTransactionEdit--transactionNote').value = transaction.transactionNote ?? ''; - modalElement.querySelector('#lotOccupancyTransactionEdit--transactionDateString').value = transaction.transactionDateString ?? ''; - modalElement.querySelector('#lotOccupancyTransactionEdit--transactionTimeString').value = transaction.transactionTimeString ?? ''; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - los.initializeDatePickers(modalElement); - modalElement.querySelector('#lotOccupancyTransactionEdit--transactionAmount').focus(); - modalElement.querySelector('form')?.addEventListener('submit', doEdit); - editCloseModalFunction = closeModalFunction; - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); -} -function deleteLotOccupancyTransaction(clickEvent) { - const transactionIndex = clickEvent.currentTarget.closest('.container--lotOccupancyTransaction').dataset.transactionIndex; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyTransaction`, { - lotOccupancyId, - transactionIndex - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyTransactions = responseJSON.lotOccupancyTransactions; - renderLotOccupancyTransactions(); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Transaction', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: 'Delete Trasnaction', - message: 'Are you sure you want to delete this transaction?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Transaction', - callbackFunction: doDelete - } - }); -} -function renderLotOccupancyTransactions() { - if (lotOccupancyTransactions.length === 0) { - // eslint-disable-next-line no-unsanitized/property - lotOccupancyTransactionsContainerElement.innerHTML = `
-

There are no transactions associated with this record.

-
`; - return; - } - // eslint-disable-next-line no-unsanitized/property - lotOccupancyTransactionsContainerElement.innerHTML = ` - - - - - - - - - - - - -
Date${los.escapedAliases.ExternalReceiptNumber}AmountOptions
Transaction Total
`; - let transactionGrandTotal = 0; - for (const lotOccupancyTransaction of lotOccupancyTransactions) { - transactionGrandTotal += lotOccupancyTransaction.transactionAmount; - const tableRowElement = document.createElement('tr'); - tableRowElement.className = 'container--lotOccupancyTransaction'; - tableRowElement.dataset.transactionIndex = - lotOccupancyTransaction.transactionIndex?.toString(); - let externalReceiptNumberHTML = ''; - if (lotOccupancyTransaction.externalReceiptNumber !== '') { - externalReceiptNumberHTML = cityssm.escapeHTML(lotOccupancyTransaction.externalReceiptNumber ?? ''); - if (los.dynamicsGPIntegrationIsEnabled) { - if (lotOccupancyTransaction.dynamicsGPDocument === undefined) { - externalReceiptNumberHTML += ` - - `; - } - else if (lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(2) === lotOccupancyTransaction.transactionAmount.toFixed(2)) { - externalReceiptNumberHTML += ` - - `; - } - else { - externalReceiptNumberHTML += ` - - `; - } - } - externalReceiptNumberHTML += '
'; - } - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` - ${cityssm.escapeHTML(lotOccupancyTransaction.transactionDateString ?? '')} - - - ${externalReceiptNumberHTML} - ${cityssm.escapeHTML(lotOccupancyTransaction.transactionNote ?? '')} - - - $${cityssm.escapeHTML(lotOccupancyTransaction.transactionAmount.toFixed(2))} - - -
- - -
- `; - tableRowElement - .querySelector('.button--edit') - ?.addEventListener('click', editLotOccupancyTransaction); - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteLotOccupancyTransaction); - lotOccupancyTransactionsContainerElement - .querySelector('tbody') - ?.append(tableRowElement); - } - ; - lotOccupancyTransactionsContainerElement.querySelector('#lotOccupancyTransactions--grandTotal').textContent = `$${transactionGrandTotal.toFixed(2)}`; - const feeGrandTotal = getFeeGrandTotal(); - if (feeGrandTotal.toFixed(2) !== transactionGrandTotal.toFixed(2)) { - lotOccupancyTransactionsContainerElement.insertAdjacentHTML('afterbegin', `
-
-
-
-
Outstanding Balance
-
-
-
- $${cityssm.escapeHTML((feeGrandTotal - transactionGrandTotal).toFixed(2))} -
-
-
-
`); - } -} -const addTransactionButtonElement = document.querySelector('#button--addTransaction'); -addTransactionButtonElement.addEventListener('click', () => { - let transactionAmountElement; - let externalReceiptNumberElement; - let addCloseModalFunction; - function doAddTransaction(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyTransaction`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyTransactions = responseJSON.lotOccupancyTransactions; - addCloseModalFunction(); - renderLotOccupancyTransactions(); - } - else { - bulmaJS.confirm({ - title: 'Error Adding Transaction', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - // eslint-disable-next-line @typescript-eslint/naming-convention - function dynamicsGP_refreshExternalReceiptNumberIcon() { - const externalReceiptNumber = externalReceiptNumberElement.value; - const iconElement = externalReceiptNumberElement - .closest('.control') - ?.querySelector('.icon'); - const helpTextElement = externalReceiptNumberElement - .closest('.field') - ?.querySelector('.help'); - if (externalReceiptNumber === '') { - helpTextElement.innerHTML = ' '; - iconElement.innerHTML = ''; - return; - } - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doGetDynamicsGPDocument`, { - externalReceiptNumber - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (!responseJSON.success || - responseJSON.dynamicsGPDocument === undefined) { - helpTextElement.textContent = 'No Matching Document Found'; - iconElement.innerHTML = - ''; - } - else if (transactionAmountElement.valueAsNumber === - responseJSON.dynamicsGPDocument.documentTotal) { - helpTextElement.textContent = 'Matching Document Found'; - iconElement.innerHTML = - ''; - } - else { - helpTextElement.textContent = `Matching Document: $${responseJSON.dynamicsGPDocument.documentTotal.toFixed(2)}`; - iconElement.innerHTML = - ''; - } - }); - } - cityssm.openHtmlModal('lotOccupancy-addTransaction', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotOccupancyTransactionAdd--lotOccupancyId').value = lotOccupancyId.toString(); - const feeGrandTotal = getFeeGrandTotal(); - const transactionGrandTotal = getTransactionGrandTotal(); - transactionAmountElement = modalElement.querySelector('#lotOccupancyTransactionAdd--transactionAmount'); - transactionAmountElement.min = (-1 * transactionGrandTotal).toFixed(2); - transactionAmountElement.max = Math.max(feeGrandTotal - transactionGrandTotal, 0).toFixed(2); - transactionAmountElement.value = Math.max(feeGrandTotal - transactionGrandTotal, 0).toFixed(2); - if (los.dynamicsGPIntegrationIsEnabled) { - externalReceiptNumberElement = modalElement.querySelector( - // eslint-disable-next-line no-secrets/no-secrets - '#lotOccupancyTransactionAdd--externalReceiptNumber'); - const externalReceiptNumberControlElement = externalReceiptNumberElement.closest('.control'); - externalReceiptNumberControlElement.classList.add('has-icons-right'); - externalReceiptNumberControlElement.insertAdjacentHTML('beforeend', ''); - externalReceiptNumberControlElement.insertAdjacentHTML('afterend', '

'); - externalReceiptNumberElement.addEventListener('change', dynamicsGP_refreshExternalReceiptNumberIcon); - transactionAmountElement.addEventListener('change', dynamicsGP_refreshExternalReceiptNumberIcon); - dynamicsGP_refreshExternalReceiptNumberIcon(); - } - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - transactionAmountElement.focus(); - addCloseModalFunction = closeModalFunction; - modalElement - .querySelector('form') - ?.addEventListener('submit', doAddTransaction); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - addTransactionButtonElement.focus(); - } - }); -}); -renderLotOccupancyFees(); diff --git a/public-typescript/lotOccupancyEdit/lotOccupancyEditFees.ts b/public-typescript/lotOccupancyEdit/lotOccupancyEditFees.ts deleted file mode 100644 index d7123d0d..00000000 --- a/public-typescript/lotOccupancyEdit/lotOccupancyEditFees.ts +++ /dev/null @@ -1,1054 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ - -import type { BulmaJS } from '@cityssm/bulma-js/types.js' -import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' - -import type { LOS } from '../../types/globalTypes.js' -import type { - DynamicsGPDocument, - Fee, - FeeCategory, - LotOccupancyFee, - LotOccupancyTransaction -} from '../../types/recordTypes.js' - -declare const cityssm: cityssmGlobal -declare const bulmaJS: BulmaJS - -declare const los: LOS - -declare const lotOccupancyId: string - -declare const exports: Record - -let lotOccupancyFees = exports.lotOccupancyFees as LotOccupancyFee[] -delete exports.lotOccupancyFees - -const lotOccupancyFeesContainerElement = document.querySelector( - '#container--lotOccupancyFees' -) as HTMLElement - -function getFeeGrandTotal(): number { - let feeGrandTotal = 0 - - for (const lotOccupancyFee of lotOccupancyFees) { - feeGrandTotal += - ((lotOccupancyFee.feeAmount ?? 0) + (lotOccupancyFee.taxAmount ?? 0)) * - (lotOccupancyFee.quantity ?? 0) - } - - return feeGrandTotal -} - -function editLotOccupancyFeeQuantity(clickEvent: Event): void { - const feeId = Number.parseInt( - (clickEvent.currentTarget as HTMLButtonElement).closest('tr')?.dataset - .feeId ?? '', - 10 - ) - - const fee = lotOccupancyFees.find((possibleFee) => { - return possibleFee.feeId === feeId - }) as LotOccupancyFee - - let updateCloseModalFunction: () => void - - function doUpdateQuantity(formEvent: SubmitEvent): void { - formEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyFeeQuantity`, - formEvent.currentTarget, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - lotOccupancyFees: LotOccupancyFee[] - } - - if (responseJSON.success) { - lotOccupancyFees = responseJSON.lotOccupancyFees - renderLotOccupancyFees() - updateCloseModalFunction() - } else { - bulmaJS.alert({ - title: 'Error Updating Quantity', - message: 'Please try again.', - contextualColorName: 'danger' - }) - } - } - ) - } - - cityssm.openHtmlModal('lotOccupancy-editFeeQuantity', { - onshow(modalElement) { - ;( - modalElement.querySelector( - '#lotOccupancyFeeQuantity--lotOccupancyId' - ) as HTMLInputElement - ).value = lotOccupancyId - ;( - modalElement.querySelector( - '#lotOccupancyFeeQuantity--feeId' - ) as HTMLInputElement - ).value = fee.feeId.toString() - ;( - modalElement.querySelector( - '#lotOccupancyFeeQuantity--quantity' - ) as HTMLInputElement - ).valueAsNumber = fee.quantity ?? 0 - ;( - modalElement.querySelector( - '#lotOccupancyFeeQuantity--quantityUnit' - ) as HTMLElement - ).textContent = fee.quantityUnit ?? '' - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped() - - updateCloseModalFunction = closeModalFunction - ;( - modalElement.querySelector( - '#lotOccupancyFeeQuantity--quantity' - ) as HTMLInputElement - ).focus() - - modalElement - .querySelector('form') - ?.addEventListener('submit', doUpdateQuantity) - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - } - }) -} - -function deleteLotOccupancyFee(clickEvent: Event): void { - const feeId = ( - (clickEvent.currentTarget as HTMLElement).closest( - '.container--lotOccupancyFee' - ) as HTMLElement - ).dataset.feeId - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyFee`, - { - lotOccupancyId, - feeId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - lotOccupancyFees: LotOccupancyFee[] - } - - if (responseJSON.success) { - lotOccupancyFees = responseJSON.lotOccupancyFees - renderLotOccupancyFees() - } else { - bulmaJS.alert({ - title: 'Error Deleting Fee', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - bulmaJS.confirm({ - title: 'Delete Fee', - message: 'Are you sure you want to delete this fee?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Fee', - callbackFunction: doDelete - } - }) -} - -function renderLotOccupancyFees(): void { - if (lotOccupancyFees.length === 0) { - lotOccupancyFeesContainerElement.innerHTML = `
-

There are no fees associated with this record.

-
` - - renderLotOccupancyTransactions() - - return - } - - // eslint-disable-next-line no-secrets/no-secrets - lotOccupancyFeesContainerElement.innerHTML = ` - - - - - - - - - - - - - - - - - - - - - - -
FeeUnit Cost×QuantityequalsTotalOptions
Subtotal
Tax
Grand Total
` - - let feeAmountTotal = 0 - let taxAmountTotal = 0 - - for (const lotOccupancyFee of lotOccupancyFees) { - const tableRowElement = document.createElement('tr') - tableRowElement.className = 'container--lotOccupancyFee' - tableRowElement.dataset.feeId = lotOccupancyFee.feeId.toString() - tableRowElement.dataset.includeQuantity = - lotOccupancyFee.includeQuantity ?? false ? '1' : '0' - - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` - ${cityssm.escapeHTML(lotOccupancyFee.feeName ?? '')}
- ${cityssm.escapeHTML(lotOccupancyFee.feeCategory ?? '')} - - ${ - lotOccupancyFee.quantity === 1 - ? '' - : ` - $${lotOccupancyFee.feeAmount?.toFixed(2)} - - × - ${lotOccupancyFee.quantity?.toString()} - =` - } - - $${((lotOccupancyFee.feeAmount ?? 0) * (lotOccupancyFee.quantity ?? 0)).toFixed(2)} - - -
- ${ - lotOccupancyFee.includeQuantity ?? false - ? `` - : '' - } - -
- ` - - tableRowElement - .querySelector('.button--editQuantity') - ?.addEventListener('click', editLotOccupancyFeeQuantity) - - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteLotOccupancyFee) - - lotOccupancyFeesContainerElement - .querySelector('tbody') - ?.append(tableRowElement) - - feeAmountTotal += - (lotOccupancyFee.feeAmount ?? 0) * (lotOccupancyFee.quantity ?? 0) - - taxAmountTotal += - (lotOccupancyFee.taxAmount ?? 0) * (lotOccupancyFee.quantity ?? 0) - } - - ;( - lotOccupancyFeesContainerElement.querySelector( - '#lotOccupancyFees--feeAmountTotal' - ) as HTMLElement - ).textContent = `$${feeAmountTotal.toFixed(2)}` - ;( - lotOccupancyFeesContainerElement.querySelector( - '#lotOccupancyFees--taxAmountTotal' - ) as HTMLElement - ).textContent = `$${taxAmountTotal.toFixed(2)}` - ;( - lotOccupancyFeesContainerElement.querySelector( - '#lotOccupancyFees--grandTotal' - ) as HTMLElement - ).textContent = `$${(feeAmountTotal + taxAmountTotal).toFixed(2)}` - - renderLotOccupancyTransactions() -} - -const addFeeButtonElement = document.querySelector( - '#button--addFee' -) as HTMLButtonElement - -addFeeButtonElement.addEventListener('click', () => { - if (los.hasUnsavedChanges()) { - bulmaJS.alert({ - message: 'Please save all unsaved changes before adding fees.', - contextualColorName: 'warning' - }) - return - } - - let feeCategories: FeeCategory[] - - let feeFilterElement: HTMLInputElement - let feeFilterResultsElement: HTMLElement - - function doAddFeeCategory(clickEvent: Event): void { - clickEvent.preventDefault() - - const feeCategoryId = Number.parseInt( - (clickEvent.currentTarget as HTMLElement).dataset.feeCategoryId ?? '', - 10 - ) - - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doAddLotOccupancyFeeCategory`, - { - lotOccupancyId, - feeCategoryId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - lotOccupancyFees: LotOccupancyFee[] - } - - if (responseJSON.success) { - lotOccupancyFees = responseJSON.lotOccupancyFees - renderLotOccupancyFees() - - bulmaJS.alert({ - message: 'Fee Group Added Successfully', - contextualColorName: 'success' - }) - - } else { - bulmaJS.alert({ - title: 'Error Adding Fee', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - function doAddFee(feeId: number, quantity: number | string = 1): void { - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doAddLotOccupancyFee`, - { - lotOccupancyId, - feeId, - quantity - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - lotOccupancyFees: LotOccupancyFee[] - } - - if (responseJSON.success) { - lotOccupancyFees = responseJSON.lotOccupancyFees - renderLotOccupancyFees() - filterFees() - } else { - bulmaJS.alert({ - title: 'Error Adding Fee', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - function doSetQuantityAndAddFee(fee: Fee): void { - let quantityElement: HTMLInputElement - let quantityCloseModalFunction: () => void - - function doSetQuantity(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - doAddFee(fee.feeId, quantityElement.value) - quantityCloseModalFunction() - } - - cityssm.openHtmlModal('lotOccupancy-setFeeQuantity', { - onshow(modalElement) { - ;( - modalElement.querySelector( - '#lotOccupancyFeeQuantity--quantityUnit' - ) as HTMLElement - ).textContent = fee.quantityUnit ?? '' - }, - onshown(modalElement, closeModalFunction) { - quantityCloseModalFunction = closeModalFunction - - quantityElement = modalElement.querySelector( - '#lotOccupancyFeeQuantity--quantity' - ) as HTMLInputElement - - modalElement - .querySelector('form') - ?.addEventListener('submit', doSetQuantity) - } - }) - } - - function tryAddFee(clickEvent: Event): void { - clickEvent.preventDefault() - - const feeId = Number.parseInt( - (clickEvent.currentTarget as HTMLElement).dataset.feeId ?? '', - 10 - ) - const feeCategoryId = Number.parseInt( - (clickEvent.currentTarget as HTMLElement).dataset.feeCategoryId ?? '', - 10 - ) - - const feeCategory = feeCategories.find((currentFeeCategory) => { - return currentFeeCategory.feeCategoryId === feeCategoryId - }) as FeeCategory - - const fee = feeCategory.fees.find((currentFee) => { - return currentFee.feeId === feeId - }) as Fee - - if (fee.includeQuantity ?? false) { - doSetQuantityAndAddFee(fee) - } else { - doAddFee(feeId) - } - } - - function filterFees(): void { - const filterStringPieces = feeFilterElement.value - .trim() - .toLowerCase() - .split(' ') - - feeFilterResultsElement.innerHTML = '' - - for (const feeCategory of feeCategories) { - const categoryContainerElement = document.createElement('div') - - categoryContainerElement.className = 'container--feeCategory' - - categoryContainerElement.dataset.feeCategoryId = - feeCategory.feeCategoryId.toString() - - categoryContainerElement.innerHTML = `
-
-

- ${cityssm.escapeHTML(feeCategory.feeCategory ?? '')} -

-
-
-
` - - if (feeCategory.isGroupedFee) { - // eslint-disable-next-line no-unsanitized/method - categoryContainerElement.querySelector('.columns')?.insertAdjacentHTML( - 'beforeend', - `
- -
` - ) - - categoryContainerElement.querySelector('button')?.addEventListener('click', doAddFeeCategory) - } - - let hasFees = false - - for (const fee of feeCategory.fees) { - // Don't include already applied fees that limit quantity - if ( - lotOccupancyFeesContainerElement.querySelector( - `.container--lotOccupancyFee[data-fee-id='${fee.feeId}'][data-include-quantity='0']` - ) !== null - ) { - continue - } - - let includeFee = true - - const feeSearchString = - `${feeCategory.feeCategory ?? ''} ${fee.feeName ?? ''} ${fee.feeDescription ?? ''}`.toLowerCase() - - for (const filterStringPiece of filterStringPieces) { - if (!feeSearchString.includes(filterStringPiece)) { - includeFee = false - break - } - } - - if (!includeFee) { - continue - } - - hasFees = true - - const panelBlockElement = document.createElement( - feeCategory.isGroupedFee ? 'div' : 'a' - ) - panelBlockElement.className = 'panel-block is-block container--fee' - panelBlockElement.dataset.feeId = fee.feeId.toString() - panelBlockElement.dataset.feeCategoryId = - feeCategory.feeCategoryId.toString() - - // eslint-disable-next-line no-unsanitized/property - panelBlockElement.innerHTML = `${cityssm.escapeHTML(fee.feeName ?? '')}
- - ${ - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - cityssm - .escapeHTML(fee.feeDescription ?? '') - .replaceAll('\n', '
') - } -
` - - if (!feeCategory.isGroupedFee) { - ;(panelBlockElement as HTMLAnchorElement).href = '#' - panelBlockElement.addEventListener('click', tryAddFee) - } - ;( - categoryContainerElement.querySelector('.panel') as HTMLElement - ).append(panelBlockElement) - } - - if (hasFees) { - feeFilterResultsElement.append(categoryContainerElement) - } - } - } - - cityssm.openHtmlModal('lotOccupancy-addFee', { - onshow(modalElement) { - feeFilterElement = modalElement.querySelector( - '#feeSelect--feeName' - ) as HTMLInputElement - - feeFilterResultsElement = modalElement.querySelector( - '#resultsContainer--feeSelect' - ) as HTMLElement - - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doGetFees`, - { - lotOccupancyId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - feeCategories: FeeCategory[] - } - - feeCategories = responseJSON.feeCategories - - feeFilterElement.disabled = false - feeFilterElement.addEventListener('keyup', filterFees) - feeFilterElement.focus() - - filterFees() - } - ) - }, - onshown() { - bulmaJS.toggleHtmlClipped() - }, - onhidden() { - renderLotOccupancyFees() - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - addFeeButtonElement.focus() - } - }) -}) - -let lotOccupancyTransactions = - exports.lotOccupancyTransactions as LotOccupancyTransaction[] -delete exports.lotOccupancyTransactions - -const lotOccupancyTransactionsContainerElement = document.querySelector( - '#container--lotOccupancyTransactions' -) as HTMLElement - -function getTransactionGrandTotal(): number { - let transactionGrandTotal = 0 - - for (const lotOccupancyTransaction of lotOccupancyTransactions) { - transactionGrandTotal += lotOccupancyTransaction.transactionAmount - } - - return transactionGrandTotal -} - -function editLotOccupancyTransaction(clickEvent: Event): void { - const transactionIndex = Number.parseInt( - (clickEvent.currentTarget as HTMLButtonElement).closest('tr')?.dataset - .transactionIndex ?? '', - 10 - ) - - const transaction = lotOccupancyTransactions.find((possibleTransaction) => { - return possibleTransaction.transactionIndex === transactionIndex - }) as LotOccupancyTransaction - - let editCloseModalFunction: () => void - - function doEdit(formEvent: SubmitEvent): void { - formEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyTransaction`, - formEvent.currentTarget, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - lotOccupancyTransactions: LotOccupancyTransaction[] - } - - if (responseJSON.success) { - lotOccupancyTransactions = responseJSON.lotOccupancyTransactions - renderLotOccupancyTransactions() - editCloseModalFunction() - } else { - bulmaJS.alert({ - title: 'Error Updating Transaction', - message: 'Please try again.', - contextualColorName: 'danger' - }) - } - } - ) - } - - cityssm.openHtmlModal('lotOccupancy-editTransaction', { - onshow(modalElement) { - los.populateAliases(modalElement) - ;( - modalElement.querySelector( - '#lotOccupancyTransactionEdit--lotOccupancyId' - ) as HTMLInputElement - ).value = lotOccupancyId - ;( - modalElement.querySelector( - '#lotOccupancyTransactionEdit--transactionIndex' - ) as HTMLInputElement - ).value = transaction.transactionIndex?.toString() ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyTransactionEdit--transactionAmount' - ) as HTMLInputElement - ).value = transaction.transactionAmount.toFixed(2) - ;( - modalElement.querySelector( - '#lotOccupancyTransactionEdit--externalReceiptNumber' - ) as HTMLInputElement - ).value = transaction.externalReceiptNumber ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyTransactionEdit--transactionNote' - ) as HTMLTextAreaElement - ).value = transaction.transactionNote ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyTransactionEdit--transactionDateString' - ) as HTMLInputElement - ).value = transaction.transactionDateString ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyTransactionEdit--transactionTimeString' - ) as HTMLInputElement - ).value = transaction.transactionTimeString ?? '' - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped() - - los.initializeDatePickers(modalElement) - ;( - modalElement.querySelector( - '#lotOccupancyTransactionEdit--transactionAmount' - ) as HTMLInputElement - ).focus() - - modalElement.querySelector('form')?.addEventListener('submit', doEdit) - - editCloseModalFunction = closeModalFunction - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - } - }) -} - -function deleteLotOccupancyTransaction(clickEvent: Event): void { - const transactionIndex = ( - (clickEvent.currentTarget as HTMLElement).closest( - '.container--lotOccupancyTransaction' - ) as HTMLElement - ).dataset.transactionIndex - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyTransaction`, - { - lotOccupancyId, - transactionIndex - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - lotOccupancyTransactions: LotOccupancyTransaction[] - } - - if (responseJSON.success) { - lotOccupancyTransactions = responseJSON.lotOccupancyTransactions - renderLotOccupancyTransactions() - } else { - bulmaJS.alert({ - title: 'Error Deleting Transaction', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - bulmaJS.confirm({ - title: 'Delete Trasnaction', - message: 'Are you sure you want to delete this transaction?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Transaction', - callbackFunction: doDelete - } - }) -} - -function renderLotOccupancyTransactions(): void { - if (lotOccupancyTransactions.length === 0) { - // eslint-disable-next-line no-unsanitized/property - lotOccupancyTransactionsContainerElement.innerHTML = `
-

There are no transactions associated with this record.

-
` - - return - } - - // eslint-disable-next-line no-unsanitized/property - lotOccupancyTransactionsContainerElement.innerHTML = ` - - - - - - - - - - - - -
Date${los.escapedAliases.ExternalReceiptNumber}AmountOptions
Transaction Total
` - - let transactionGrandTotal = 0 - - for (const lotOccupancyTransaction of lotOccupancyTransactions) { - transactionGrandTotal += lotOccupancyTransaction.transactionAmount - - const tableRowElement = document.createElement('tr') - tableRowElement.className = 'container--lotOccupancyTransaction' - tableRowElement.dataset.transactionIndex = - lotOccupancyTransaction.transactionIndex?.toString() - - let externalReceiptNumberHTML = '' - - if (lotOccupancyTransaction.externalReceiptNumber !== '') { - externalReceiptNumberHTML = cityssm.escapeHTML( - lotOccupancyTransaction.externalReceiptNumber ?? '' - ) - - if (los.dynamicsGPIntegrationIsEnabled) { - if (lotOccupancyTransaction.dynamicsGPDocument === undefined) { - externalReceiptNumberHTML += ` - - ` - } else if ( - lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed( - 2 - ) === lotOccupancyTransaction.transactionAmount.toFixed(2) - ) { - externalReceiptNumberHTML += ` - - ` - } else { - externalReceiptNumberHTML += ` - - ` - } - } - - externalReceiptNumberHTML += '
' - } - - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` - ${cityssm.escapeHTML(lotOccupancyTransaction.transactionDateString ?? '')} - - - ${externalReceiptNumberHTML} - ${cityssm.escapeHTML(lotOccupancyTransaction.transactionNote ?? '')} - - - $${cityssm.escapeHTML(lotOccupancyTransaction.transactionAmount.toFixed(2))} - - -
- - -
- ` - - tableRowElement - .querySelector('.button--edit') - ?.addEventListener('click', editLotOccupancyTransaction) - - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteLotOccupancyTransaction) - - lotOccupancyTransactionsContainerElement - .querySelector('tbody') - ?.append(tableRowElement) - } - - ;( - lotOccupancyTransactionsContainerElement.querySelector( - '#lotOccupancyTransactions--grandTotal' - ) as HTMLElement - ).textContent = `$${transactionGrandTotal.toFixed(2)}` - - const feeGrandTotal = getFeeGrandTotal() - - if (feeGrandTotal.toFixed(2) !== transactionGrandTotal.toFixed(2)) { - lotOccupancyTransactionsContainerElement.insertAdjacentHTML( - 'afterbegin', - `
-
-
-
-
Outstanding Balance
-
-
-
- $${cityssm.escapeHTML((feeGrandTotal - transactionGrandTotal).toFixed(2))} -
-
-
-
` - ) - } -} - -const addTransactionButtonElement = document.querySelector( - '#button--addTransaction' -) as HTMLButtonElement - -addTransactionButtonElement.addEventListener('click', () => { - let transactionAmountElement: HTMLInputElement - let externalReceiptNumberElement: HTMLInputElement - - let addCloseModalFunction: () => void - - function doAddTransaction(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doAddLotOccupancyTransaction`, - submitEvent.currentTarget, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - lotOccupancyTransactions: LotOccupancyTransaction[] - } - - if (responseJSON.success) { - lotOccupancyTransactions = responseJSON.lotOccupancyTransactions - addCloseModalFunction() - renderLotOccupancyTransactions() - } else { - bulmaJS.confirm({ - title: 'Error Adding Transaction', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - // eslint-disable-next-line @typescript-eslint/naming-convention - function dynamicsGP_refreshExternalReceiptNumberIcon(): void { - const externalReceiptNumber = externalReceiptNumberElement.value - - const iconElement = externalReceiptNumberElement - .closest('.control') - ?.querySelector('.icon') as HTMLElement - - const helpTextElement = externalReceiptNumberElement - .closest('.field') - ?.querySelector('.help') as HTMLElement - - if (externalReceiptNumber === '') { - helpTextElement.innerHTML = ' ' - iconElement.innerHTML = '' - return - } - - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doGetDynamicsGPDocument`, - { - externalReceiptNumber - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - dynamicsGPDocument?: DynamicsGPDocument - } - - if ( - !responseJSON.success || - responseJSON.dynamicsGPDocument === undefined - ) { - helpTextElement.textContent = 'No Matching Document Found' - iconElement.innerHTML = - '' - } else if ( - transactionAmountElement.valueAsNumber === - responseJSON.dynamicsGPDocument.documentTotal - ) { - helpTextElement.textContent = 'Matching Document Found' - iconElement.innerHTML = - '' - } else { - helpTextElement.textContent = `Matching Document: $${responseJSON.dynamicsGPDocument.documentTotal.toFixed(2)}` - iconElement.innerHTML = - '' - } - } - ) - } - - cityssm.openHtmlModal('lotOccupancy-addTransaction', { - onshow(modalElement) { - los.populateAliases(modalElement) - ;( - modalElement.querySelector( - '#lotOccupancyTransactionAdd--lotOccupancyId' - ) as HTMLInputElement - ).value = lotOccupancyId.toString() - - const feeGrandTotal = getFeeGrandTotal() - const transactionGrandTotal = getTransactionGrandTotal() - - transactionAmountElement = modalElement.querySelector( - '#lotOccupancyTransactionAdd--transactionAmount' - ) as HTMLInputElement - - transactionAmountElement.min = (-1 * transactionGrandTotal).toFixed(2) - - transactionAmountElement.max = Math.max( - feeGrandTotal - transactionGrandTotal, - 0 - ).toFixed(2) - - transactionAmountElement.value = Math.max( - feeGrandTotal - transactionGrandTotal, - 0 - ).toFixed(2) - - if (los.dynamicsGPIntegrationIsEnabled) { - externalReceiptNumberElement = modalElement.querySelector( - // eslint-disable-next-line no-secrets/no-secrets - '#lotOccupancyTransactionAdd--externalReceiptNumber' - ) as HTMLInputElement - - const externalReceiptNumberControlElement = - externalReceiptNumberElement.closest('.control') as HTMLElement - - externalReceiptNumberControlElement.classList.add('has-icons-right') - - externalReceiptNumberControlElement.insertAdjacentHTML( - 'beforeend', - '' - ) - - externalReceiptNumberControlElement.insertAdjacentHTML( - 'afterend', - '

' - ) - - externalReceiptNumberElement.addEventListener( - 'change', - dynamicsGP_refreshExternalReceiptNumberIcon - ) - - transactionAmountElement.addEventListener( - 'change', - dynamicsGP_refreshExternalReceiptNumberIcon - ) - - dynamicsGP_refreshExternalReceiptNumberIcon() - } - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped() - - transactionAmountElement.focus() - - addCloseModalFunction = closeModalFunction - - modalElement - .querySelector('form') - ?.addEventListener('submit', doAddTransaction) - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - addTransactionButtonElement.focus() - } - }) -}) - -renderLotOccupancyFees() diff --git a/public-typescript/lotOccupancyEdit/lotOccupancyEditOccupants.d.ts b/public-typescript/lotOccupancyEdit/lotOccupancyEditOccupants.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/public-typescript/lotOccupancyEdit/lotOccupancyEditOccupants.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/public-typescript/lotOccupancyEdit/lotOccupancyEditOccupants.js b/public-typescript/lotOccupancyEdit/lotOccupancyEditOccupants.js deleted file mode 100644 index a3254845..00000000 --- a/public-typescript/lotOccupancyEdit/lotOccupancyEditOccupants.js +++ /dev/null @@ -1,392 +0,0 @@ -"use strict"; -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -let lotOccupancyOccupants = exports.lotOccupancyOccupants; -delete exports.lotOccupancyOccupants; -function openEditLotOccupancyOccupant(clickEvent) { - const lotOccupantIndex = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .lotOccupantIndex ?? '', 10); - const lotOccupancyOccupant = lotOccupancyOccupants.find((currentLotOccupancyOccupant) => { - return currentLotOccupancyOccupant.lotOccupantIndex === lotOccupantIndex; - }); - let editFormElement; - let editCloseModalFunction; - function editOccupant(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyOccupant`, editFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyOccupants = responseJSON.lotOccupancyOccupants; - editCloseModalFunction(); - renderLotOccupancyOccupants(); - } - else { - bulmaJS.alert({ - title: `Error Updating ${los.escapedAliases.Occupant}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lotOccupancy-editOccupant', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotOccupancyOccupantEdit--lotOccupancyId').value = lotOccupancyId; - modalElement.querySelector('#lotOccupancyOccupantEdit--lotOccupantIndex').value = lotOccupantIndex.toString(); - const lotOccupantTypeSelectElement = modalElement.querySelector('#lotOccupancyOccupantEdit--lotOccupantTypeId'); - let lotOccupantTypeSelected = false; - for (const lotOccupantType of exports.lotOccupantTypes) { - const optionElement = document.createElement('option'); - optionElement.value = lotOccupantType.lotOccupantTypeId.toString(); - optionElement.textContent = lotOccupantType.lotOccupantType; - optionElement.dataset.occupantCommentTitle = - lotOccupantType.occupantCommentTitle; - optionElement.dataset.fontAwesomeIconClass = - lotOccupantType.fontAwesomeIconClass; - if (lotOccupantType.lotOccupantTypeId === - lotOccupancyOccupant.lotOccupantTypeId) { - optionElement.selected = true; - lotOccupantTypeSelected = true; - } - lotOccupantTypeSelectElement.append(optionElement); - } - if (!lotOccupantTypeSelected) { - const optionElement = document.createElement('option'); - optionElement.value = - lotOccupancyOccupant.lotOccupantTypeId?.toString() ?? ''; - optionElement.textContent = lotOccupancyOccupant.lotOccupantType ?? ''; - optionElement.dataset.occupantCommentTitle = - lotOccupancyOccupant.occupantCommentTitle; - optionElement.dataset.fontAwesomeIconClass = - lotOccupancyOccupant.fontAwesomeIconClass; - optionElement.selected = true; - lotOccupantTypeSelectElement.append(optionElement); - } - ; - modalElement.querySelector('#lotOccupancyOccupantEdit--fontAwesomeIconClass').innerHTML = - ``; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantName').value = lotOccupancyOccupant.occupantName ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantFamilyName').value = lotOccupancyOccupant.occupantFamilyName ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantAddress1').value = lotOccupancyOccupant.occupantAddress1 ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantAddress2').value = lotOccupancyOccupant.occupantAddress2 ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantCity').value = lotOccupancyOccupant.occupantCity ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantProvince').value = lotOccupancyOccupant.occupantProvince ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantPostalCode').value = lotOccupancyOccupant.occupantPostalCode ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantPhoneNumber').value = lotOccupancyOccupant.occupantPhoneNumber ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantEmailAddress').value = lotOccupancyOccupant.occupantEmailAddress ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantCommentTitle').textContent = - (lotOccupancyOccupant.occupantCommentTitle ?? '') === '' - ? 'Comment' - : lotOccupancyOccupant.occupantCommentTitle ?? ''; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantComment').value = lotOccupancyOccupant.occupantComment ?? ''; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - const lotOccupantTypeIdElement = modalElement.querySelector('#lotOccupancyOccupantEdit--lotOccupantTypeId'); - lotOccupantTypeIdElement.focus(); - lotOccupantTypeIdElement.addEventListener('change', () => { - const fontAwesomeIconClass = lotOccupantTypeIdElement.selectedOptions[0].dataset - .fontAwesomeIconClass ?? 'user'; - modalElement.querySelector('#lotOccupancyOccupantEdit--fontAwesomeIconClass').innerHTML = - ``; - let occupantCommentTitle = lotOccupantTypeIdElement.selectedOptions[0].dataset - .occupantCommentTitle ?? ''; - if (occupantCommentTitle === '') { - occupantCommentTitle = 'Comment'; - } - ; - modalElement.querySelector('#lotOccupancyOccupantEdit--occupantCommentTitle').textContent = occupantCommentTitle; - }); - editFormElement = modalElement.querySelector('form'); - editFormElement.addEventListener('submit', editOccupant); - editCloseModalFunction = closeModalFunction; - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); -} -function deleteLotOccupancyOccupant(clickEvent) { - const lotOccupantIndex = clickEvent.currentTarget.closest('tr')?.dataset.lotOccupantIndex; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyOccupant`, { - lotOccupancyId, - lotOccupantIndex - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyOccupants = responseJSON.lotOccupancyOccupants; - renderLotOccupancyOccupants(); - } - else { - bulmaJS.alert({ - title: `Error Removing ${los.escapedAliases.Occupant}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: `Remove ${los.escapedAliases.Occupant}?`, - message: `Are you sure you want to remove this ${los.escapedAliases.occupant}?`, - okButton: { - text: `Yes, Remove ${los.escapedAliases.Occupant}`, - callbackFunction: doDelete - }, - contextualColorName: 'warning' - }); -} -function renderLotOccupancyOccupants() { - const occupantsContainer = document.querySelector('#container--lotOccupancyOccupants'); - cityssm.clearElement(occupantsContainer); - if (lotOccupancyOccupants.length === 0) { - // eslint-disable-next-line no-unsanitized/property - occupantsContainer.innerHTML = `
-

There are no ${los.escapedAliases.occupants} associated with this record.

-
`; - return; - } - const tableElement = document.createElement('table'); - tableElement.className = 'table is-fullwidth is-striped is-hoverable'; - // eslint-disable-next-line no-unsanitized/property - tableElement.innerHTML = ` - ${los.escapedAliases.Occupant} - Address - Other Contact - Comment - Options - - `; - for (const lotOccupancyOccupant of lotOccupancyOccupants) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.lotOccupantIndex = - lotOccupancyOccupant.lotOccupantIndex?.toString(); - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` - ${cityssm.escapeHTML((lotOccupancyOccupant.occupantName ?? '') === '' && - (lotOccupancyOccupant.occupantFamilyName ?? '') === '' - ? '(No Name)' - : `${lotOccupancyOccupant.occupantName} ${lotOccupancyOccupant.occupantFamilyName}`)}
- - - ${cityssm.escapeHTML(lotOccupancyOccupant.lotOccupantType ?? '')} - - - ${(lotOccupancyOccupant.occupantAddress1 ?? '') === '' - ? '' - : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress1 ?? '')}
`} - ${(lotOccupancyOccupant.occupantAddress2 ?? '') === '' - ? '' - : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress2 ?? '')}
`} - ${(lotOccupancyOccupant.occupantCity ?? '') === '' - ? '' - : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantCity ?? '')}, `} - ${cityssm.escapeHTML(lotOccupancyOccupant.occupantProvince ?? '')}
- ${cityssm.escapeHTML(lotOccupancyOccupant.occupantPostalCode ?? '')} - - ${(lotOccupancyOccupant.occupantPhoneNumber ?? '') === '' - ? '' - : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantPhoneNumber ?? '')}
`} - ${(lotOccupancyOccupant.occupantEmailAddress ?? '') === '' - ? '' - : cityssm.escapeHTML(lotOccupancyOccupant.occupantEmailAddress ?? '')} - - - ${cityssm.escapeHTML(lotOccupancyOccupant.occupantComment ?? '')} - - -
- - -
- `; - tableRowElement - .querySelector('.button--edit') - ?.addEventListener('click', openEditLotOccupancyOccupant); - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteLotOccupancyOccupant); - tableElement.querySelector('tbody')?.append(tableRowElement); - } - occupantsContainer.append(tableElement); -} -if (isCreate) { - const lotOccupantTypeIdElement = document.querySelector('#lotOccupancy--lotOccupantTypeId'); - lotOccupantTypeIdElement.addEventListener('change', () => { - const occupantFields = formElement.querySelectorAll("[data-table='LotOccupancyOccupant']"); - for (const occupantField of occupantFields) { - occupantField.disabled = lotOccupantTypeIdElement.value === ''; - } - let occupantCommentTitle = lotOccupantTypeIdElement.selectedOptions[0].dataset - .occupantCommentTitle ?? ''; - if (occupantCommentTitle === '') { - occupantCommentTitle = 'Comment'; - } - ; - formElement.querySelector('#lotOccupancy--occupantCommentTitle').textContent = occupantCommentTitle; - }); -} -else { - renderLotOccupancyOccupants(); -} -document - .querySelector('#button--addOccupant') - ?.addEventListener('click', () => { - let addCloseModalFunction; - let addFormElement; - let searchFormElement; - let searchResultsElement; - function addOccupant(formOrObject) { - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyOccupant`, formOrObject, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - lotOccupancyOccupants = responseJSON.lotOccupancyOccupants; - addCloseModalFunction(); - renderLotOccupancyOccupants(); - } - else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Occupant}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function addOccupantFromForm(submitEvent) { - submitEvent.preventDefault(); - addOccupant(addFormElement); - } - let pastOccupantSearchResults = []; - function addOccupantFromCopy(clickEvent) { - clickEvent.preventDefault(); - const panelBlockElement = clickEvent.currentTarget; - const occupant = pastOccupantSearchResults[Number.parseInt(panelBlockElement.dataset.index ?? '', 10)]; - const lotOccupantTypeId = (panelBlockElement - .closest('.modal') - ?.querySelector('#lotOccupancyOccupantCopy--lotOccupantTypeId')).value; - if (lotOccupantTypeId === '') { - bulmaJS.alert({ - title: `No ${los.escapedAliases.Occupant} Type Selected`, - message: `Select a type to apply to the newly added ${los.escapedAliases.occupant}.`, - contextualColorName: 'warning' - }); - } - else { - occupant.lotOccupantTypeId = Number.parseInt(lotOccupantTypeId, 10); - occupant.lotOccupancyId = Number.parseInt(lotOccupancyId, 10); - addOccupant(occupant); - } - } - function searchOccupants(event) { - event.preventDefault(); - if (searchFormElement.querySelector('#lotOccupancyOccupantCopy--searchFilter').value === '') { - searchResultsElement.innerHTML = `
-

Enter a partial name or address in the search field above.

-
`; - return; - } - // eslint-disable-next-line no-unsanitized/property - searchResultsElement.innerHTML = - los.getLoadingParagraphHTML('Searching...'); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doSearchPastOccupants`, searchFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - pastOccupantSearchResults = responseJSON.occupants; - const panelElement = document.createElement('div'); - panelElement.className = 'panel'; - for (const [index, occupant] of pastOccupantSearchResults.entries()) { - const panelBlockElement = document.createElement('a'); - panelBlockElement.className = 'panel-block is-block'; - panelBlockElement.href = '#'; - panelBlockElement.dataset.index = index.toString(); - // eslint-disable-next-line no-unsanitized/property - panelBlockElement.innerHTML = ` - ${cityssm.escapeHTML(occupant.occupantName ?? '')} ${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')} -
-
-
- ${cityssm.escapeHTML(occupant.occupantAddress1 ?? '')}
- ${(occupant.occupantAddress2 ?? '') === '' - ? '' - : `${cityssm.escapeHTML(occupant.occupantAddress2 ?? '')}
`}${cityssm.escapeHTML(occupant.occupantCity ?? '')}, ${cityssm.escapeHTML(occupant.occupantProvince ?? '')}
- ${cityssm.escapeHTML(occupant.occupantPostalCode ?? '')} -
-
- ${(occupant.occupantPhoneNumber ?? '') === '' - ? '' - : `${cityssm.escapeHTML(occupant.occupantPhoneNumber ?? '')}
`} - ${cityssm.escapeHTML(occupant.occupantEmailAddress ?? '')}
-
-
`; - panelBlockElement.addEventListener('click', addOccupantFromCopy); - panelElement.append(panelBlockElement); - } - searchResultsElement.innerHTML = ''; - searchResultsElement.append(panelElement); - }); - } - cityssm.openHtmlModal('lotOccupancy-addOccupant', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotOccupancyOccupantAdd--lotOccupancyId').value = lotOccupancyId; - const lotOccupantTypeSelectElement = modalElement.querySelector('#lotOccupancyOccupantAdd--lotOccupantTypeId'); - const lotOccupantTypeCopySelectElement = modalElement.querySelector('#lotOccupancyOccupantCopy--lotOccupantTypeId'); - for (const lotOccupantType of exports.lotOccupantTypes) { - const optionElement = document.createElement('option'); - optionElement.value = lotOccupantType.lotOccupantTypeId.toString(); - optionElement.textContent = lotOccupantType.lotOccupantType; - optionElement.dataset.occupantCommentTitle = - lotOccupantType.occupantCommentTitle; - optionElement.dataset.fontAwesomeIconClass = - lotOccupantType.fontAwesomeIconClass; - lotOccupantTypeSelectElement.append(optionElement); - lotOccupantTypeCopySelectElement.append(optionElement.cloneNode(true)); - } - ; - modalElement.querySelector('#lotOccupancyOccupantAdd--occupantCity').value = exports.occupantCityDefault; - modalElement.querySelector('#lotOccupancyOccupantAdd--occupantProvince').value = exports.occupantProvinceDefault; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - bulmaJS.init(modalElement); - const lotOccupantTypeIdElement = modalElement.querySelector('#lotOccupancyOccupantAdd--lotOccupantTypeId'); - lotOccupantTypeIdElement.focus(); - lotOccupantTypeIdElement.addEventListener('change', () => { - const fontAwesomeIconClass = lotOccupantTypeIdElement.selectedOptions[0].dataset - .fontAwesomeIconClass ?? 'user'; - modalElement.querySelector('#lotOccupancyOccupantAdd--fontAwesomeIconClass').innerHTML = - ``; - let occupantCommentTitle = lotOccupantTypeIdElement.selectedOptions[0].dataset - .occupantCommentTitle ?? ''; - if (occupantCommentTitle === '') { - occupantCommentTitle = 'Comment'; - } - ; - modalElement.querySelector('#lotOccupancyOccupantAdd--occupantCommentTitle').textContent = occupantCommentTitle; - }); - addFormElement = modalElement.querySelector('#form--lotOccupancyOccupantAdd'); - addFormElement.addEventListener('submit', addOccupantFromForm); - searchResultsElement = modalElement.querySelector('#lotOccupancyOccupantCopy--searchResults'); - searchFormElement = modalElement.querySelector('#form--lotOccupancyOccupantCopy'); - searchFormElement.addEventListener('submit', (formEvent) => { - formEvent.preventDefault(); - }); - modalElement.querySelector('#lotOccupancyOccupantCopy--searchFilter').addEventListener('change', searchOccupants); - addCloseModalFunction = closeModalFunction; - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#button--addOccupant').focus(); - } - }); -}); diff --git a/public-typescript/lotOccupancyEdit/lotOccupancyEditOccupants.ts b/public-typescript/lotOccupancyEdit/lotOccupancyEditOccupants.ts deleted file mode 100644 index a1ff656b..00000000 --- a/public-typescript/lotOccupancyEdit/lotOccupancyEditOccupants.ts +++ /dev/null @@ -1,693 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ - -import type { BulmaJS } from '@cityssm/bulma-js/types.js' -import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' - -import type { LOS } from '../../types/globalTypes.js' -import type { - LotOccupancyOccupant, - LotOccupantType -} from '../../types/recordTypes.js' - -declare const cityssm: cityssmGlobal -declare const bulmaJS: BulmaJS - -declare const los: LOS - -declare const lotOccupancyId: string -declare const isCreate: boolean -declare const formElement: HTMLFormElement - -declare const exports: Record - -let lotOccupancyOccupants = - exports.lotOccupancyOccupants as LotOccupancyOccupant[] - -delete exports.lotOccupancyOccupants - -function openEditLotOccupancyOccupant(clickEvent: Event): void { - const lotOccupantIndex = Number.parseInt( - (clickEvent.currentTarget as HTMLElement).closest('tr')?.dataset - .lotOccupantIndex ?? '', - 10 - ) - - const lotOccupancyOccupant = lotOccupancyOccupants.find( - (currentLotOccupancyOccupant) => { - return currentLotOccupancyOccupant.lotOccupantIndex === lotOccupantIndex - } - ) as LotOccupancyOccupant - - let editFormElement: HTMLFormElement - let editCloseModalFunction: () => void - - function editOccupant(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyOccupant`, - editFormElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - lotOccupancyOccupants: LotOccupancyOccupant[] - } - - if (responseJSON.success) { - lotOccupancyOccupants = responseJSON.lotOccupancyOccupants - editCloseModalFunction() - renderLotOccupancyOccupants() - } else { - bulmaJS.alert({ - title: `Error Updating ${los.escapedAliases.Occupant}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - cityssm.openHtmlModal('lotOccupancy-editOccupant', { - onshow(modalElement) { - los.populateAliases(modalElement) - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--lotOccupancyId' - ) as HTMLInputElement - ).value = lotOccupancyId - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--lotOccupantIndex' - ) as HTMLInputElement - ).value = lotOccupantIndex.toString() - - const lotOccupantTypeSelectElement = modalElement.querySelector( - '#lotOccupancyOccupantEdit--lotOccupantTypeId' - ) as HTMLSelectElement - - let lotOccupantTypeSelected = false - - for (const lotOccupantType of exports.lotOccupantTypes as LotOccupantType[]) { - const optionElement = document.createElement('option') - optionElement.value = lotOccupantType.lotOccupantTypeId.toString() - optionElement.textContent = lotOccupantType.lotOccupantType - - optionElement.dataset.occupantCommentTitle = - lotOccupantType.occupantCommentTitle - - optionElement.dataset.fontAwesomeIconClass = - lotOccupantType.fontAwesomeIconClass - - if ( - lotOccupantType.lotOccupantTypeId === - lotOccupancyOccupant.lotOccupantTypeId - ) { - optionElement.selected = true - lotOccupantTypeSelected = true - } - - lotOccupantTypeSelectElement.append(optionElement) - } - - if (!lotOccupantTypeSelected) { - const optionElement = document.createElement('option') - - optionElement.value = - lotOccupancyOccupant.lotOccupantTypeId?.toString() ?? '' - optionElement.textContent = lotOccupancyOccupant.lotOccupantType ?? '' - - optionElement.dataset.occupantCommentTitle = - lotOccupancyOccupant.occupantCommentTitle - - optionElement.dataset.fontAwesomeIconClass = - lotOccupancyOccupant.fontAwesomeIconClass - - optionElement.selected = true - - lotOccupantTypeSelectElement.append(optionElement) - } - - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--fontAwesomeIconClass' - ) as HTMLElement - ).innerHTML = - `` - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--occupantName' - ) as HTMLInputElement - ).value = lotOccupancyOccupant.occupantName ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--occupantFamilyName' - ) as HTMLInputElement - ).value = lotOccupancyOccupant.occupantFamilyName ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--occupantAddress1' - ) as HTMLInputElement - ).value = lotOccupancyOccupant.occupantAddress1 ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--occupantAddress2' - ) as HTMLInputElement - ).value = lotOccupancyOccupant.occupantAddress2 ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--occupantCity' - ) as HTMLInputElement - ).value = lotOccupancyOccupant.occupantCity ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--occupantProvince' - ) as HTMLInputElement - ).value = lotOccupancyOccupant.occupantProvince ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--occupantPostalCode' - ) as HTMLInputElement - ).value = lotOccupancyOccupant.occupantPostalCode ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--occupantPhoneNumber' - ) as HTMLInputElement - ).value = lotOccupancyOccupant.occupantPhoneNumber ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--occupantEmailAddress' - ) as HTMLInputElement - ).value = lotOccupancyOccupant.occupantEmailAddress ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--occupantCommentTitle' - ) as HTMLLabelElement - ).textContent = - (lotOccupancyOccupant.occupantCommentTitle ?? '') === '' - ? 'Comment' - : lotOccupancyOccupant.occupantCommentTitle ?? '' - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--occupantComment' - ) as HTMLTextAreaElement - ).value = lotOccupancyOccupant.occupantComment ?? '' - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped() - - const lotOccupantTypeIdElement = modalElement.querySelector( - '#lotOccupancyOccupantEdit--lotOccupantTypeId' - ) as HTMLSelectElement - - lotOccupantTypeIdElement.focus() - - lotOccupantTypeIdElement.addEventListener('change', () => { - const fontAwesomeIconClass = - lotOccupantTypeIdElement.selectedOptions[0].dataset - .fontAwesomeIconClass ?? 'user' - - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--fontAwesomeIconClass' - ) as HTMLElement - ).innerHTML = - `` - - let occupantCommentTitle = - lotOccupantTypeIdElement.selectedOptions[0].dataset - .occupantCommentTitle ?? '' - if (occupantCommentTitle === '') { - occupantCommentTitle = 'Comment' - } - - ;( - modalElement.querySelector( - '#lotOccupancyOccupantEdit--occupantCommentTitle' - ) as HTMLLabelElement - ).textContent = occupantCommentTitle - }) - - editFormElement = modalElement.querySelector('form') as HTMLFormElement - editFormElement.addEventListener('submit', editOccupant) - - editCloseModalFunction = closeModalFunction - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - } - }) -} - -function deleteLotOccupancyOccupant(clickEvent: Event): void { - const lotOccupantIndex = (clickEvent.currentTarget as HTMLElement).closest( - 'tr' - )?.dataset.lotOccupantIndex - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyOccupant`, - { - lotOccupancyId, - lotOccupantIndex - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - lotOccupancyOccupants: LotOccupancyOccupant[] - } - - if (responseJSON.success) { - lotOccupancyOccupants = responseJSON.lotOccupancyOccupants - renderLotOccupancyOccupants() - } else { - bulmaJS.alert({ - title: `Error Removing ${los.escapedAliases.Occupant}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - bulmaJS.confirm({ - title: `Remove ${los.escapedAliases.Occupant}?`, - message: `Are you sure you want to remove this ${los.escapedAliases.occupant}?`, - okButton: { - text: `Yes, Remove ${los.escapedAliases.Occupant}`, - callbackFunction: doDelete - }, - contextualColorName: 'warning' - }) -} - -function renderLotOccupancyOccupants(): void { - const occupantsContainer = document.querySelector( - '#container--lotOccupancyOccupants' - ) as HTMLElement - - cityssm.clearElement(occupantsContainer) - - if (lotOccupancyOccupants.length === 0) { - // eslint-disable-next-line no-unsanitized/property - occupantsContainer.innerHTML = `
-

There are no ${los.escapedAliases.occupants} associated with this record.

-
` - - return - } - - const tableElement = document.createElement('table') - tableElement.className = 'table is-fullwidth is-striped is-hoverable' - - // eslint-disable-next-line no-unsanitized/property - tableElement.innerHTML = ` - ${los.escapedAliases.Occupant} - Address - Other Contact - Comment - Options - - ` - - for (const lotOccupancyOccupant of lotOccupancyOccupants) { - const tableRowElement = document.createElement('tr') - tableRowElement.dataset.lotOccupantIndex = - lotOccupancyOccupant.lotOccupantIndex?.toString() - - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` - ${cityssm.escapeHTML( - (lotOccupancyOccupant.occupantName ?? '') === '' && - (lotOccupancyOccupant.occupantFamilyName ?? '') === '' - ? '(No Name)' - : `${lotOccupancyOccupant.occupantName} ${lotOccupancyOccupant.occupantFamilyName}` - )}
- - - ${cityssm.escapeHTML(lotOccupancyOccupant.lotOccupantType ?? '')} - - - ${ - (lotOccupancyOccupant.occupantAddress1 ?? '') === '' - ? '' - : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress1 ?? '')}
` - } - ${ - (lotOccupancyOccupant.occupantAddress2 ?? '') === '' - ? '' - : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress2 ?? '')}
` - } - ${ - (lotOccupancyOccupant.occupantCity ?? '') === '' - ? '' - : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantCity ?? '')}, ` - } - ${cityssm.escapeHTML(lotOccupancyOccupant.occupantProvince ?? '')}
- ${cityssm.escapeHTML(lotOccupancyOccupant.occupantPostalCode ?? '')} - - ${ - (lotOccupancyOccupant.occupantPhoneNumber ?? '') === '' - ? '' - : `${cityssm.escapeHTML( - lotOccupancyOccupant.occupantPhoneNumber ?? '' - )}
` - } - ${ - (lotOccupancyOccupant.occupantEmailAddress ?? '') === '' - ? '' - : cityssm.escapeHTML( - lotOccupancyOccupant.occupantEmailAddress ?? '' - ) - } - - - ${cityssm.escapeHTML(lotOccupancyOccupant.occupantComment ?? '')} - - -
- - -
- ` - - tableRowElement - .querySelector('.button--edit') - ?.addEventListener('click', openEditLotOccupancyOccupant) - - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteLotOccupancyOccupant) - - tableElement.querySelector('tbody')?.append(tableRowElement) - } - - occupantsContainer.append(tableElement) -} - -if (isCreate) { - const lotOccupantTypeIdElement = document.querySelector( - '#lotOccupancy--lotOccupantTypeId' - ) as HTMLSelectElement - - lotOccupantTypeIdElement.addEventListener('change', () => { - const occupantFields: NodeListOf = - formElement.querySelectorAll("[data-table='LotOccupancyOccupant']") - - for (const occupantField of occupantFields) { - occupantField.disabled = lotOccupantTypeIdElement.value === '' - } - - let occupantCommentTitle = - lotOccupantTypeIdElement.selectedOptions[0].dataset - .occupantCommentTitle ?? '' - if (occupantCommentTitle === '') { - occupantCommentTitle = 'Comment' - } - - ;( - formElement.querySelector( - '#lotOccupancy--occupantCommentTitle' - ) as HTMLElement - ).textContent = occupantCommentTitle - }) -} else { - renderLotOccupancyOccupants() -} - -document - .querySelector('#button--addOccupant') - ?.addEventListener('click', () => { - let addCloseModalFunction: () => void - - let addFormElement: HTMLFormElement - - let searchFormElement: HTMLFormElement - let searchResultsElement: HTMLElement - - function addOccupant( - formOrObject: HTMLFormElement | LotOccupancyOccupant - ): void { - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doAddLotOccupancyOccupant`, - formOrObject, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - lotOccupancyOccupants: LotOccupancyOccupant[] - } - - if (responseJSON.success) { - lotOccupancyOccupants = responseJSON.lotOccupancyOccupants - addCloseModalFunction() - renderLotOccupancyOccupants() - } else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Occupant}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - function addOccupantFromForm(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - addOccupant(addFormElement) - } - - let pastOccupantSearchResults: LotOccupancyOccupant[] = [] - - function addOccupantFromCopy(clickEvent: MouseEvent): void { - clickEvent.preventDefault() - - const panelBlockElement = clickEvent.currentTarget as HTMLElement - - const occupant = - pastOccupantSearchResults[ - Number.parseInt(panelBlockElement.dataset.index ?? '', 10) - ] - - const lotOccupantTypeId = ( - panelBlockElement - .closest('.modal') - ?.querySelector( - '#lotOccupancyOccupantCopy--lotOccupantTypeId' - ) as HTMLSelectElement - ).value - - if (lotOccupantTypeId === '') { - bulmaJS.alert({ - title: `No ${los.escapedAliases.Occupant} Type Selected`, - message: `Select a type to apply to the newly added ${los.escapedAliases.occupant}.`, - contextualColorName: 'warning' - }) - } else { - occupant.lotOccupantTypeId = Number.parseInt(lotOccupantTypeId, 10) - occupant.lotOccupancyId = Number.parseInt(lotOccupancyId, 10) - addOccupant(occupant) - } - } - - function searchOccupants(event: Event): void { - event.preventDefault() - - if ( - ( - searchFormElement.querySelector( - '#lotOccupancyOccupantCopy--searchFilter' - ) as HTMLInputElement - ).value === '' - ) { - searchResultsElement.innerHTML = `
-

Enter a partial name or address in the search field above.

-
` - - return - } - - // eslint-disable-next-line no-unsanitized/property - searchResultsElement.innerHTML = - los.getLoadingParagraphHTML('Searching...') - - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doSearchPastOccupants`, - searchFormElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - occupants: LotOccupancyOccupant[] - } - - pastOccupantSearchResults = responseJSON.occupants - - const panelElement = document.createElement('div') - panelElement.className = 'panel' - - for (const [index, occupant] of pastOccupantSearchResults.entries()) { - const panelBlockElement = document.createElement('a') - panelBlockElement.className = 'panel-block is-block' - panelBlockElement.href = '#' - panelBlockElement.dataset.index = index.toString() - - // eslint-disable-next-line no-unsanitized/property - panelBlockElement.innerHTML = ` - ${cityssm.escapeHTML(occupant.occupantName ?? '')} ${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')} -
-
-
- ${cityssm.escapeHTML(occupant.occupantAddress1 ?? '')}
- ${ - (occupant.occupantAddress2 ?? '') === '' - ? '' - : `${cityssm.escapeHTML(occupant.occupantAddress2 ?? '')}
` - }${cityssm.escapeHTML(occupant.occupantCity ?? '')}, ${cityssm.escapeHTML(occupant.occupantProvince ?? '')}
- ${cityssm.escapeHTML(occupant.occupantPostalCode ?? '')} -
-
- ${ - (occupant.occupantPhoneNumber ?? '') === '' - ? '' - : `${cityssm.escapeHTML(occupant.occupantPhoneNumber ?? '')}
` - } - ${cityssm.escapeHTML(occupant.occupantEmailAddress ?? '')}
-
-
` - - panelBlockElement.addEventListener('click', addOccupantFromCopy) - - panelElement.append(panelBlockElement) - } - - searchResultsElement.innerHTML = '' - searchResultsElement.append(panelElement) - } - ) - } - - cityssm.openHtmlModal('lotOccupancy-addOccupant', { - onshow(modalElement) { - los.populateAliases(modalElement) - ;( - modalElement.querySelector( - '#lotOccupancyOccupantAdd--lotOccupancyId' - ) as HTMLInputElement - ).value = lotOccupancyId - - const lotOccupantTypeSelectElement = modalElement.querySelector( - '#lotOccupancyOccupantAdd--lotOccupantTypeId' - ) as HTMLSelectElement - - const lotOccupantTypeCopySelectElement = modalElement.querySelector( - '#lotOccupancyOccupantCopy--lotOccupantTypeId' - ) as HTMLSelectElement - - for (const lotOccupantType of exports.lotOccupantTypes as LotOccupantType[]) { - const optionElement = document.createElement('option') - optionElement.value = lotOccupantType.lotOccupantTypeId.toString() - optionElement.textContent = lotOccupantType.lotOccupantType - - optionElement.dataset.occupantCommentTitle = - lotOccupantType.occupantCommentTitle - - optionElement.dataset.fontAwesomeIconClass = - lotOccupantType.fontAwesomeIconClass - - lotOccupantTypeSelectElement.append(optionElement) - - lotOccupantTypeCopySelectElement.append(optionElement.cloneNode(true)) - } - - ;( - modalElement.querySelector( - '#lotOccupancyOccupantAdd--occupantCity' - ) as HTMLInputElement - ).value = exports.occupantCityDefault as string - ;( - modalElement.querySelector( - '#lotOccupancyOccupantAdd--occupantProvince' - ) as HTMLInputElement - ).value = exports.occupantProvinceDefault as string - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped() - bulmaJS.init(modalElement) - - const lotOccupantTypeIdElement = modalElement.querySelector( - '#lotOccupancyOccupantAdd--lotOccupantTypeId' - ) as HTMLSelectElement - - lotOccupantTypeIdElement.focus() - - lotOccupantTypeIdElement.addEventListener('change', () => { - const fontAwesomeIconClass = - lotOccupantTypeIdElement.selectedOptions[0].dataset - .fontAwesomeIconClass ?? 'user' - - ;( - modalElement.querySelector( - '#lotOccupancyOccupantAdd--fontAwesomeIconClass' - ) as HTMLElement - ).innerHTML = - `` - - let occupantCommentTitle = - lotOccupantTypeIdElement.selectedOptions[0].dataset - .occupantCommentTitle ?? '' - - if (occupantCommentTitle === '') { - occupantCommentTitle = 'Comment' - } - - ;( - modalElement.querySelector( - '#lotOccupancyOccupantAdd--occupantCommentTitle' - ) as HTMLElement - ).textContent = occupantCommentTitle - }) - - addFormElement = modalElement.querySelector( - '#form--lotOccupancyOccupantAdd' - ) as HTMLFormElement - addFormElement.addEventListener('submit', addOccupantFromForm) - - searchResultsElement = modalElement.querySelector( - '#lotOccupancyOccupantCopy--searchResults' - ) as HTMLElement - - searchFormElement = modalElement.querySelector( - '#form--lotOccupancyOccupantCopy' - ) as HTMLFormElement - searchFormElement.addEventListener('submit', (formEvent) => { - formEvent.preventDefault() - }) - ;( - modalElement.querySelector( - '#lotOccupancyOccupantCopy--searchFilter' - ) as HTMLInputElement - ).addEventListener('change', searchOccupants) - - addCloseModalFunction = closeModalFunction - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - ;( - document.querySelector('#button--addOccupant') as HTMLButtonElement - ).focus() - } - }) - }) diff --git a/public-typescript/workOrderEdit.js b/public-typescript/workOrderEdit.js deleted file mode 100644 index 57aea459..00000000 --- a/public-typescript/workOrderEdit.js +++ /dev/null @@ -1,1259 +0,0 @@ -"use strict"; -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -(() => { - const los = exports.los; - const workOrderId = document.querySelector('#workOrderEdit--workOrderId').value; - const isCreate = workOrderId === ''; - const workOrderFormElement = document.querySelector('#form--workOrderEdit'); - los.initializeDatePickers(workOrderFormElement - .querySelector('#workOrderEdit--workOrderOpenDateString') - ?.closest('.field')); - los.initializeUnlockFieldButtons(workOrderFormElement); - function setUnsavedChanges() { - los.setUnsavedChanges(); - document - .querySelector("button[type='submit'][form='form--workOrderEdit']") - ?.classList.remove('is-light'); - } - function clearUnsavedChanges() { - los.clearUnsavedChanges(); - document - .querySelector("button[type='submit'][form='form--workOrderEdit']") - ?.classList.add('is-light'); - } - workOrderFormElement.addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/workOrders/${isCreate ? 'doCreateWorkOrder' : 'doUpdateWorkOrder'}`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - clearUnsavedChanges(); - if (isCreate) { - window.location.href = los.getWorkOrderURL(responseJSON.workOrderId, true); - } - else { - bulmaJS.alert({ - message: 'Work Order Updated Successfully', - contextualColorName: 'success' - }); - } - } - else { - bulmaJS.alert({ - title: 'Error Updating Work Order', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - }); - const inputElements = workOrderFormElement.querySelectorAll('input, select, textarea'); - for (const inputElement of inputElements) { - inputElement.addEventListener('change', setUnsavedChanges); - } - /* - * Work Order Options - */ - function doClose() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doCloseWorkOrder`, { - workOrderId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - clearUnsavedChanges(); - window.location.href = los.getWorkOrderURL(workOrderId); - } - else { - bulmaJS.alert({ - title: 'Error Closing Work Order', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrder`, { - workOrderId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - clearUnsavedChanges(); - window.location.href = `${los.urlPrefix}/workOrders`; - } - else { - bulmaJS.alert({ - title: 'Error Deleting Work Order', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - let workOrderMilestones; - document - .querySelector('#button--closeWorkOrder') - ?.addEventListener('click', () => { - const hasOpenMilestones = workOrderMilestones.some((milestone) => { - return !milestone.workOrderMilestoneCompletionDate; - }); - if (hasOpenMilestones) { - bulmaJS.alert({ - title: 'Outstanding Milestones', - message: `You cannot close a work order with outstanding milestones. - Either complete the outstanding milestones, or remove them from the work order.`, - contextualColorName: 'warning' - }); - /* - // Disable closing work orders with open milestones - bulmaJS.confirm({ - title: "Close Work Order with Outstanding Milestones", - message: - "Are you sure you want to close this work order with outstanding milestones?", - contextualColorName: "danger", - okButton: { - text: "Yes, Close Work Order", - callbackFunction: doClose - } - }); - */ - } - else { - bulmaJS.confirm({ - title: 'Close Work Order', - message: los.hasUnsavedChanges() - ? 'Are you sure you want to close this work order with unsaved changes?' - : 'Are you sure you want to close this work order?', - contextualColorName: los.hasUnsavedChanges() ? 'warning' : 'info', - okButton: { - text: 'Yes, Close Work Order', - callbackFunction: doClose - } - }); - } - }); - document - .querySelector('#button--deleteWorkOrder') - ?.addEventListener('click', (clickEvent) => { - clickEvent.preventDefault(); - bulmaJS.confirm({ - title: 'Delete Work Order', - message: 'Are you sure you want to delete this work order?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Work Order', - callbackFunction: doDelete - } - }); - }); - /* - * Related Lots - */ - if (!isCreate) { - "use strict"; - // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair - /* eslint-disable unicorn/prefer-module */ - Object.defineProperty(exports, "__esModule", { value: true }); - let workOrderLots = exports.workOrderLots; - delete exports.workOrderLots; - let workOrderLotOccupancies = exports.workOrderLotOccupancies; - delete exports.workOrderLotOccupancies; - function deleteLotOccupancy(clickEvent) { - const lotOccupancyId = clickEvent.currentTarget.closest('.container--lotOccupancy').dataset.lotOccupancyId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrderLotOccupancy`, { - workOrderId, - lotOccupancyId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderLotOccupancies = responseJSON.workOrderLotOccupancies; - renderRelatedLotsAndOccupancies(); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Relationship', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Occupancy} Relationship`, - message: `Are you sure you want to remove the relationship to this ${los.escapedAliases.occupancy} record from this work order? Note that the record will remain.`, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Relationship', - callbackFunction: doDelete - } - }); - } - function addLot(lotId, callbackFunction) { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderLot`, { - workOrderId, - lotId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderLots = responseJSON.workOrderLots; - renderRelatedLotsAndOccupancies(); - } - else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Lot}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - if (callbackFunction !== undefined) { - callbackFunction(responseJSON.success); - } - }); - } - function addLotOccupancy(lotOccupancyId, callbackFunction) { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderLotOccupancy`, { - workOrderId, - lotOccupancyId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderLotOccupancies = responseJSON.workOrderLotOccupancies; - renderRelatedLotsAndOccupancies(); - } - else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Occupancy}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - if (callbackFunction !== undefined) { - callbackFunction(responseJSON.success); - } - }); - } - function addLotFromLotOccupancy(clickEvent) { - const lotId = clickEvent.currentTarget.dataset.lotId ?? ''; - addLot(lotId); - } - function renderRelatedOccupancies() { - const occupanciesContainerElement = document.querySelector('#container--lotOccupancies'); - document.querySelector(".tabs a[href='#relatedTab--lotOccupancies'] .tag").textContent = workOrderLotOccupancies.length.toString(); - if (workOrderLotOccupancies.length === 0) { - // eslint-disable-next-line no-unsanitized/property - occupanciesContainerElement.innerHTML = `
-

There are no ${los.escapedAliases.occupancies} associated with this work order.

-
`; - return; - } - // eslint-disable-next-line no-unsanitized/property - occupanciesContainerElement.innerHTML = ` - - - - - - - - - - -
${los.escapedAliases.Occupancy} Type${los.escapedAliases.Lot}${los.escapedAliases.OccupancyStartDate}End Date${los.escapedAliases.Occupants}
`; - const currentDateString = cityssm.dateToString(new Date()); - for (const lotOccupancy of workOrderLotOccupancies) { - const rowElement = document.createElement('tr'); - rowElement.className = 'container--lotOccupancy'; - rowElement.dataset.lotOccupancyId = lotOccupancy.lotOccupancyId.toString(); - const isActive = !(lotOccupancy.occupancyEndDate && - lotOccupancy.occupancyEndDateString < currentDateString); - const hasLotRecord = lotOccupancy.lotId && - workOrderLots.some((lot) => { - return lotOccupancy.lotId === lot.lotId; - }); - // eslint-disable-next-line no-unsanitized/property - rowElement.innerHTML = ` - ${isActive - ? `` - : ``} - - - ${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')} -
- #${lotOccupancy.lotOccupancyId} - `; - if (lotOccupancy.lotId) { - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML('beforeend', ` - ${cityssm.escapeHTML(lotOccupancy.lotName ?? '')} - ${hasLotRecord - ? '' - : ` `} - `); - } - else { - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML('beforeend', `(No ${los.escapedAliases.Lot})`); - } - let occupantsHTML = ''; - for (const occupant of lotOccupancy.lotOccupancyOccupants) { - occupantsHTML += `
  • - - - - ${cityssm.escapeHTML(occupant.occupantName ?? '')} - ${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')} -
  • `; - } - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML('beforeend', ` - ${lotOccupancy.occupancyStartDateString} - - ${lotOccupancy.occupancyEndDate - ? lotOccupancy.occupancyEndDateString - : '(No End Date)'} - - ${lotOccupancy.lotOccupancyOccupants.length === 0 - ? `(No ${los.escapedAliases.Occupants})` - : `
      ${occupantsHTML}
    `} - - - `); - rowElement - .querySelector('.button--addLot') - ?.addEventListener('click', addLotFromLotOccupancy); - rowElement - .querySelector('.button--deleteLotOccupancy') - ?.addEventListener('click', deleteLotOccupancy); - occupanciesContainerElement.querySelector('tbody')?.append(rowElement); - } - } - function openEditLotStatus(clickEvent) { - const lotId = Number.parseInt(clickEvent.currentTarget.closest('.container--lot').dataset.lotId ?? '', 10); - const lot = workOrderLots.find((possibleLot) => { - return possibleLot.lotId === lotId; - }); - let editCloseModalFunction; - function doUpdateLotStatus(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/workOrders/doUpdateLotStatus`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderLots = responseJSON.workOrderLots; - renderRelatedLotsAndOccupancies(); - editCloseModalFunction(); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Relationship', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lot-editLotStatus', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotStatusEdit--lotId').value = lotId.toString(); - modalElement.querySelector('#lotStatusEdit--lotName').value = lot.lotName ?? ''; - const lotStatusElement = modalElement.querySelector('#lotStatusEdit--lotStatusId'); - let lotStatusFound = false; - for (const lotStatus of exports.lotStatuses) { - const optionElement = document.createElement('option'); - optionElement.value = lotStatus.lotStatusId.toString(); - optionElement.textContent = lotStatus.lotStatus; - if (lotStatus.lotStatusId === lot.lotStatusId) { - lotStatusFound = true; - } - lotStatusElement.append(optionElement); - } - if (!lotStatusFound && lot.lotStatusId) { - const optionElement = document.createElement('option'); - optionElement.value = lot.lotStatusId.toString(); - optionElement.textContent = lot.lotStatus ?? ''; - lotStatusElement.append(optionElement); - } - if (lot.lotStatusId) { - lotStatusElement.value = lot.lotStatusId.toString(); - } - // eslint-disable-next-line no-unsanitized/method - modalElement - .querySelector('form') - ?.insertAdjacentHTML('beforeend', ``); - }, - onshown(modalElement, closeModalFunction) { - editCloseModalFunction = closeModalFunction; - bulmaJS.toggleHtmlClipped(); - modalElement - .querySelector('form') - ?.addEventListener('submit', doUpdateLotStatus); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); - } - function deleteLot(clickEvent) { - const lotId = clickEvent.currentTarget.closest('.container--lot').dataset.lotId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrderLot`, { - workOrderId, - lotId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderLots = responseJSON.workOrderLots; - renderRelatedLotsAndOccupancies(); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Relationship', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Occupancy} Relationship`, - message: `Are you sure you want to remove the relationship to this ${los.escapedAliases.occupancy} record from this work order? Note that the record will remain.`, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Relationship', - callbackFunction: doDelete - } - }); - } - function renderRelatedLots() { - const lotsContainerElement = document.querySelector('#container--lots'); - document.querySelector(".tabs a[href='#relatedTab--lots'] .tag").textContent = workOrderLots.length.toString(); - if (workOrderLots.length === 0) { - // eslint-disable-next-line no-unsanitized/property - lotsContainerElement.innerHTML = `
    -

    There are no ${los.escapedAliases.lots} associated with this work order.

    -
    `; - return; - } - // eslint-disable-next-line no-unsanitized/property - lotsContainerElement.innerHTML = ` - - - - - - - - -
    ${los.escapedAliases.Lot}${los.escapedAliases.Map}${los.escapedAliases.Lot} TypeStatus
    `; - for (const lot of workOrderLots) { - const rowElement = document.createElement('tr'); - rowElement.className = 'container--lot'; - rowElement.dataset.lotId = lot.lotId.toString(); - // eslint-disable-next-line no-unsanitized/property - rowElement.innerHTML = ` - - ${cityssm.escapeHTML(lot.lotName ?? '')} - - - ${cityssm.escapeHTML(lot.mapName ?? '')} - - ${cityssm.escapeHTML(lot.lotType ?? '')} - - ${lot.lotStatusId - ? cityssm.escapeHTML(lot.lotStatus ?? '') - : '(No Status)'} - - - - `; - rowElement - .querySelector('.button--editLotStatus') - ?.addEventListener('click', openEditLotStatus); - rowElement - .querySelector('.button--deleteLot') - ?.addEventListener('click', deleteLot); - lotsContainerElement.querySelector('tbody')?.append(rowElement); - } - } - function renderRelatedLotsAndOccupancies() { - renderRelatedOccupancies(); - renderRelatedLots(); - } - renderRelatedLotsAndOccupancies(); - function doAddLotOccupancy(clickEvent) { - const rowElement = clickEvent.currentTarget.closest('tr'); - const lotOccupancyId = rowElement.dataset.lotOccupancyId ?? ''; - addLotOccupancy(lotOccupancyId, (success) => { - if (success) { - rowElement.remove(); - } - }); - } - document - .querySelector('#button--addLotOccupancy') - ?.addEventListener('click', () => { - let searchFormElement; - let searchResultsContainerElement; - function doSearch(event) { - if (event) { - event.preventDefault(); - } - // eslint-disable-next-line no-unsanitized/property - searchResultsContainerElement.innerHTML = - los.getLoadingParagraphHTML('Searching...'); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doSearchLotOccupancies`, searchFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.lotOccupancies.length === 0) { - searchResultsContainerElement.innerHTML = `
    -

    There are no records that meet the search criteria.

    -
    `; - return; - } - // eslint-disable-next-line no-unsanitized/property - searchResultsContainerElement.innerHTML = ` - - - - - - - - - -
    ${los.escapedAliases.Occupancy} Type${los.escapedAliases.Lot}${los.escapedAliases.OccupancyStartDate}End Date${los.escapedAliases.Occupants}
    `; - for (const lotOccupancy of responseJSON.lotOccupancies) { - const rowElement = document.createElement('tr'); - rowElement.className = 'container--lotOccupancy'; - rowElement.dataset.lotOccupancyId = - lotOccupancy.lotOccupancyId.toString(); - rowElement.innerHTML = ` - - - - ${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')} - `; - if (lotOccupancy.lotId) { - rowElement.insertAdjacentHTML('beforeend', `${cityssm.escapeHTML(lotOccupancy.lotName ?? '')}`); - } - else { - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML('beforeend', `(No ${los.escapedAliases.Lot})`); - } - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML('beforeend', ` - ${lotOccupancy.occupancyStartDateString} - - ${lotOccupancy.occupancyEndDate - ? lotOccupancy.occupancyEndDateString - : '(No End Date)'} - - ${lotOccupancy.lotOccupancyOccupants.length === 0 - ? ` - (No ${cityssm.escapeHTML(los.escapedAliases.Occupants)}) - ` - : cityssm.escapeHTML(`${lotOccupancy.lotOccupancyOccupants[0].occupantName} - ${lotOccupancy.lotOccupancyOccupants[0] - .occupantFamilyName}`) + - (lotOccupancy.lotOccupancyOccupants.length > 1 - ? ` plus - ${(lotOccupancy.lotOccupancyOccupants.length - 1).toString()}` - : '')}`); - rowElement - .querySelector('.button--addLotOccupancy') - ?.addEventListener('click', doAddLotOccupancy); - searchResultsContainerElement - .querySelector('tbody') - ?.append(rowElement); - } - }); - } - cityssm.openHtmlModal('workOrder-addLotOccupancy', { - onshow(modalElement) { - los.populateAliases(modalElement); - searchFormElement = modalElement.querySelector('form'); - searchResultsContainerElement = modalElement.querySelector('#resultsContainer--lotOccupancyAdd'); - modalElement.querySelector('#lotOccupancySearch--notWorkOrderId').value = workOrderId; - modalElement.querySelector('#lotOccupancySearch--occupancyEffectiveDateString').value = document.querySelector('#workOrderEdit--workOrderOpenDateString').value; - doSearch(); - }, - onshown(modalElement) { - bulmaJS.toggleHtmlClipped(); - const occupantNameElement = modalElement.querySelector('#lotOccupancySearch--occupantName'); - occupantNameElement.addEventListener('change', doSearch); - occupantNameElement.focus(); - modalElement.querySelector('#lotOccupancySearch--lotName').addEventListener('change', doSearch); - searchFormElement.addEventListener('submit', doSearch); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#button--addLotOccupancy').focus(); - } - }); - }); - function doAddLot(clickEvent) { - const rowElement = clickEvent.currentTarget.closest('tr'); - const lotId = rowElement.dataset.lotId ?? ''; - addLot(lotId, (success) => { - if (success) { - rowElement.remove(); - } - }); - } - document.querySelector('#button--addLot')?.addEventListener('click', () => { - let searchFormElement; - let searchResultsContainerElement; - function doSearch(event) { - if (event) { - event.preventDefault(); - } - // eslint-disable-next-line no-unsanitized/property - searchResultsContainerElement.innerHTML = - los.getLoadingParagraphHTML('Searching...'); - cityssm.postJSON(`${los.urlPrefix}/lots/doSearchLots`, searchFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.lots.length === 0) { - searchResultsContainerElement.innerHTML = `
    -

    There are no records that meet the search criteria.

    -
    `; - return; - } - // eslint-disable-next-line no-unsanitized/property - searchResultsContainerElement.innerHTML = ` - - - - - - - - -
    ${los.escapedAliases.Lot}${los.escapedAliases.Map}${los.escapedAliases.Lot} TypeStatus
    `; - for (const lot of responseJSON.lots) { - const rowElement = document.createElement('tr'); - rowElement.className = 'container--lot'; - rowElement.dataset.lotId = lot.lotId.toString(); - rowElement.innerHTML = ` - - - ${cityssm.escapeHTML(lot.lotName ?? '')} - - ${cityssm.escapeHTML(lot.mapName ?? '')} - - ${cityssm.escapeHTML(lot.lotType ?? '')} - - ${cityssm.escapeHTML(lot.lotStatus ?? '')} - `; - rowElement - .querySelector('.button--addLot') - ?.addEventListener('click', doAddLot); - searchResultsContainerElement - .querySelector('tbody') - ?.append(rowElement); - } - }); - } - cityssm.openHtmlModal('workOrder-addLot', { - onshow(modalElement) { - los.populateAliases(modalElement); - searchFormElement = modalElement.querySelector('form'); - searchResultsContainerElement = modalElement.querySelector('#resultsContainer--lotAdd'); - modalElement.querySelector('#lotSearch--notWorkOrderId').value = workOrderId; - const lotStatusElement = modalElement.querySelector('#lotSearch--lotStatusId'); - for (const lotStatus of exports.lotStatuses) { - const optionElement = document.createElement('option'); - optionElement.value = lotStatus.lotStatusId.toString(); - optionElement.textContent = lotStatus.lotStatus; - lotStatusElement.append(optionElement); - } - doSearch(); - }, - onshown(modalElement) { - bulmaJS.toggleHtmlClipped(); - const lotNameElement = modalElement.querySelector('#lotSearch--lotName'); - lotNameElement.addEventListener('change', doSearch); - lotNameElement.focus(); - modalElement - .querySelector('#lotSearch--lotStatusId') - ?.addEventListener('change', doSearch); - searchFormElement.addEventListener('submit', doSearch); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#button--addLot').focus(); - } - }); - }); - - } - /* - * Comments - */ - "use strict"; - // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair - /* eslint-disable unicorn/prefer-module */ - Object.defineProperty(exports, "__esModule", { value: true }); - let workOrderComments = exports.workOrderComments; - delete exports.workOrderComments; - function openEditWorkOrderComment(clickEvent) { - const workOrderCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .workOrderCommentId ?? '', 10); - const workOrderComment = workOrderComments.find((currentComment) => { - return currentComment.workOrderCommentId === workOrderCommentId; - }); - let editFormElement; - let editCloseModalFunction; - function editComment(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/workOrders/doUpdateWorkOrderComment`, editFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderComments = responseJSON.workOrderComments; - editCloseModalFunction(); - renderWorkOrderComments(); - } - else { - bulmaJS.alert({ - title: 'Error Updating Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('workOrder-editComment', { - onshow(modalElement) { - ; - modalElement.querySelector('#workOrderCommentEdit--workOrderId').value = workOrderId; - modalElement.querySelector('#workOrderCommentEdit--workOrderCommentId').value = workOrderCommentId.toString(); - modalElement.querySelector('#workOrderCommentEdit--workOrderComment').value = workOrderComment.workOrderComment ?? ''; - const workOrderCommentDateStringElement = modalElement.querySelector('#workOrderCommentEdit--workOrderCommentDateString'); - workOrderCommentDateStringElement.value = - workOrderComment.workOrderCommentDateString ?? ''; - const currentDateString = cityssm.dateToString(new Date()); - workOrderCommentDateStringElement.max = - workOrderComment.workOrderCommentDateString <= currentDateString - ? currentDateString - : workOrderComment.workOrderCommentDateString ?? ''; - modalElement.querySelector('#workOrderCommentEdit--workOrderCommentTimeString').value = workOrderComment.workOrderCommentTimeString ?? ''; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - los.initializeDatePickers(modalElement); - modalElement.querySelector('#workOrderCommentEdit--workOrderComment').focus(); - editFormElement = modalElement.querySelector('form'); - editFormElement.addEventListener('submit', editComment); - editCloseModalFunction = closeModalFunction; - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); - } - function deleteWorkOrderComment(clickEvent) { - const workOrderCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .workOrderCommentId ?? '', 10); - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrderComment`, { - workOrderId, - workOrderCommentId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderComments = responseJSON.workOrderComments; - renderWorkOrderComments(); - } - else { - bulmaJS.alert({ - title: 'Error Removing Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: 'Remove Comment?', - message: 'Are you sure you want to remove this comment?', - okButton: { - text: 'Yes, Remove Comment', - callbackFunction: doDelete - }, - contextualColorName: 'warning' - }); - } - function renderWorkOrderComments() { - const containerElement = document.querySelector('#container--workOrderComments'); - if (workOrderComments.length === 0) { - containerElement.innerHTML = `
    -

    There are no comments to display.

    -
    `; - return; - } - const tableElement = document.createElement('table'); - tableElement.className = 'table is-fullwidth is-striped is-hoverable'; - tableElement.innerHTML = ` - Commentor - Comment Date - Comment - Options`; - for (const workOrderComment of workOrderComments) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.workOrderCommentId = - workOrderComment.workOrderCommentId?.toString(); - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` - ${cityssm.escapeHTML(workOrderComment.recordCreate_userName ?? '')} - - ${workOrderComment.workOrderCommentDateString} - ${workOrderComment.workOrderCommentTime === 0 - ? '' - : workOrderComment.workOrderCommentTimePeriodString} - - ${cityssm.escapeHTML(workOrderComment.workOrderComment ?? '')} - -
    - - -
    - `; - tableRowElement - .querySelector('.button--edit') - ?.addEventListener('click', openEditWorkOrderComment); - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteWorkOrderComment); - tableElement.querySelector('tbody')?.append(tableRowElement); - } - containerElement.innerHTML = ''; - containerElement.append(tableElement); - } - function openAddCommentModal() { - let addCommentCloseModalFunction; - function doAddComment(formEvent) { - formEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderComment`, formEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderComments = responseJSON.workOrderComments; - renderWorkOrderComments(); - addCommentCloseModalFunction(); - } - }); - } - cityssm.openHtmlModal('workOrder-addComment', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#workOrderCommentAdd--workOrderId').value = workOrderId; - modalElement - .querySelector('form') - ?.addEventListener('submit', doAddComment); - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - addCommentCloseModalFunction = closeModalFunction; - modalElement.querySelector('#workOrderCommentAdd--workOrderComment').focus(); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#workOrderComments--add').focus(); - } - }); - } - document - .querySelector('#workOrderComments--add') - ?.addEventListener('click', openAddCommentModal); - if (!isCreate) { - renderWorkOrderComments(); - } - - /* - * Milestones - */ - function clearPanelBlockElements(panelElement) { - for (const panelBlockElement of panelElement.querySelectorAll('.panel-block')) { - panelBlockElement.remove(); - } - } - function refreshConflictingMilestones(workOrderMilestoneDateString, targetPanelElement) { - // Clear panel-block elements - clearPanelBlockElements(targetPanelElement); - // eslint-disable-next-line no-unsanitized/method - targetPanelElement.insertAdjacentHTML('beforeend', `
    - ${los.getLoadingParagraphHTML('Loading conflicting milestones...')} -
    `); - cityssm.postJSON(`${los.urlPrefix}/workOrders/doGetWorkOrderMilestones`, { - workOrderMilestoneDateFilter: 'date', - workOrderMilestoneDateString - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - const workOrderMilestones = responseJSON.workOrderMilestones.filter((possibleMilestone) => { - return possibleMilestone.workOrderId.toString() !== workOrderId; - }); - clearPanelBlockElements(targetPanelElement); - for (const milestone of workOrderMilestones) { - targetPanelElement.insertAdjacentHTML('beforeend', `
    -
    -
    - ${cityssm.escapeHTML(milestone.workOrderMilestoneTime === 0 ? 'No Time' : milestone.workOrderMilestoneTimePeriodString ?? '')}
    - ${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')} -
    -
    - ${cityssm.escapeHTML(milestone.workOrderNumber ?? '')}
    - - ${cityssm.escapeHTML(milestone.workOrderDescription ?? '')} - -
    -
    -
    `); - } - if (workOrderMilestones.length === 0) { - targetPanelElement.insertAdjacentHTML('beforeend', `
    -
    -

    - There are no milestones on other work orders scheduled for - ${cityssm.escapeHTML(workOrderMilestoneDateString)}. -

    -
    -
    `); - } - }); - } - function processMilestoneResponse(rawResponseJSON) { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderMilestones = responseJSON.workOrderMilestones; - renderMilestones(); - } - else { - bulmaJS.alert({ - title: 'Error Reopening Milestone', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - } - function completeMilestone(clickEvent) { - clickEvent.preventDefault(); - const currentDateString = cityssm.dateToString(new Date()); - const workOrderMilestoneId = Number.parseInt(clickEvent.currentTarget.closest('.container--milestone').dataset.workOrderMilestoneId ?? '', 10); - const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { - return currentMilestone.workOrderMilestoneId === workOrderMilestoneId; - }); - function doComplete() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doCompleteWorkOrderMilestone`, { - workOrderId, - workOrderMilestoneId - }, processMilestoneResponse); - } - bulmaJS.confirm({ - title: 'Complete Milestone', - message: `Are you sure you want to complete this milestone? - ${workOrderMilestone.workOrderMilestoneDateString !== undefined && - workOrderMilestone.workOrderMilestoneDateString !== '' && - workOrderMilestone.workOrderMilestoneDateString > currentDateString - ? '
    Note that this milestone is expected to be completed in the future.' - : ''}`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Complete Milestone', - callbackFunction: doComplete - } - }); - } - function reopenMilestone(clickEvent) { - clickEvent.preventDefault(); - const workOrderMilestoneId = clickEvent.currentTarget.closest('.container--milestone').dataset.workOrderMilestoneId; - function doReopen() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doReopenWorkOrderMilestone`, { - workOrderId, - workOrderMilestoneId - }, processMilestoneResponse); - } - bulmaJS.confirm({ - title: 'Reopen Milestone', - message: 'Are you sure you want to remove the completion status from this milestone, and reopen it?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Reopen Milestone', - callbackFunction: doReopen - } - }); - } - function deleteMilestone(clickEvent) { - clickEvent.preventDefault(); - const workOrderMilestoneId = clickEvent.currentTarget.closest('.container--milestone').dataset.workOrderMilestoneId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrderMilestone`, { - workOrderMilestoneId, - workOrderId - }, processMilestoneResponse); - } - bulmaJS.confirm({ - title: 'Delete Milestone', - message: 'Are you sure you want to delete this milestone?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Milestone', - callbackFunction: doDelete - } - }); - } - function editMilestone(clickEvent) { - clickEvent.preventDefault(); - const workOrderMilestoneId = Number.parseInt(clickEvent.currentTarget.closest('.container--milestone').dataset.workOrderMilestoneId ?? '', 10); - const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { - return currentMilestone.workOrderMilestoneId === workOrderMilestoneId; - }); - let editCloseModalFunction; - let workOrderMilestoneDateStringElement; - function doEdit(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/workOrders/doUpdateWorkOrderMilestone`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - processMilestoneResponse(responseJSON); - if (responseJSON.success) { - editCloseModalFunction(); - } - }); - } - cityssm.openHtmlModal('workOrder-editMilestone', { - onshow(modalElement) { - ; - modalElement.querySelector('#milestoneEdit--workOrderId').value = workOrderId; - modalElement.querySelector('#milestoneEdit--workOrderMilestoneId').value = workOrderMilestone.workOrderMilestoneId?.toString() ?? ''; - const milestoneTypeElement = modalElement.querySelector('#milestoneEdit--workOrderMilestoneTypeId'); - let milestoneTypeFound = false; - for (const milestoneType of exports.workOrderMilestoneTypes) { - const optionElement = document.createElement('option'); - optionElement.value = - milestoneType.workOrderMilestoneTypeId.toString(); - optionElement.textContent = milestoneType.workOrderMilestoneType; - if (milestoneType.workOrderMilestoneTypeId === - workOrderMilestone.workOrderMilestoneTypeId) { - optionElement.selected = true; - milestoneTypeFound = true; - } - milestoneTypeElement.append(optionElement); - } - if (!milestoneTypeFound && - workOrderMilestone.workOrderMilestoneTypeId) { - const optionElement = document.createElement('option'); - optionElement.value = - workOrderMilestone.workOrderMilestoneTypeId.toString(); - optionElement.textContent = - workOrderMilestone.workOrderMilestoneType ?? ''; - optionElement.selected = true; - milestoneTypeElement.append(optionElement); - } - workOrderMilestoneDateStringElement = modalElement.querySelector('#milestoneEdit--workOrderMilestoneDateString'); - workOrderMilestoneDateStringElement.value = - workOrderMilestone.workOrderMilestoneDateString ?? ''; - if (workOrderMilestone.workOrderMilestoneTime) { - ; - modalElement.querySelector('#milestoneEdit--workOrderMilestoneTimeString').value = workOrderMilestone.workOrderMilestoneTimeString ?? ''; - } - ; - modalElement.querySelector('#milestoneEdit--workOrderMilestoneDescription').value = workOrderMilestone.workOrderMilestoneDescription ?? ''; - }, - onshown(modalElement, closeModalFunction) { - editCloseModalFunction = closeModalFunction; - bulmaJS.toggleHtmlClipped(); - los.initializeDatePickers(modalElement); - // los.initializeTimePickers(modalElement); - modalElement.querySelector('form')?.addEventListener('submit', doEdit); - const conflictingMilestonePanelElement = document.querySelector('#milestoneEdit--conflictingMilestonesPanel'); - workOrderMilestoneDateStringElement.addEventListener('change', () => { - refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement); - }); - refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); - } - function renderMilestones() { - // Clear milestones panel - const milestonesPanelElement = document.querySelector('#panel--milestones'); - const panelBlockElementsToDelete = milestonesPanelElement.querySelectorAll('.panel-block'); - for (const panelBlockToDelete of panelBlockElementsToDelete) { - panelBlockToDelete.remove(); - } - for (const milestone of workOrderMilestones) { - const panelBlockElement = document.createElement('div'); - panelBlockElement.className = 'panel-block is-block container--milestone'; - panelBlockElement.dataset.workOrderMilestoneId = - milestone.workOrderMilestoneId?.toString(); - // eslint-disable-next-line no-unsanitized/property - panelBlockElement.innerHTML = `
    -
    - ${milestone.workOrderMilestoneCompletionDate - ? ` - - ` - : ``} -
    - ${milestone.workOrderMilestoneTypeId - ? `${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')}
    ` - : ''} - ${milestone.workOrderMilestoneDate === 0 - ? '(No Set Date)' - : milestone.workOrderMilestoneDateString} - ${milestone.workOrderMilestoneTime - ? ` ${milestone.workOrderMilestoneTimePeriodString}` - : ''}
    - - ${cityssm.escapeHTML(milestone.workOrderMilestoneDescription ?? '')} - -
    - -
    `; - panelBlockElement - .querySelector('.button--reopenMilestone') - ?.addEventListener('click', reopenMilestone); - panelBlockElement - .querySelector('.button--editMilestone') - ?.addEventListener('click', editMilestone); - panelBlockElement - .querySelector('.button--completeMilestone') - ?.addEventListener('click', completeMilestone); - panelBlockElement - .querySelector('.button--deleteMilestone') - ?.addEventListener('click', deleteMilestone); - milestonesPanelElement.append(panelBlockElement); - } - bulmaJS.init(milestonesPanelElement); - } - if (!isCreate) { - workOrderMilestones = - exports.workOrderMilestones; - delete exports.workOrderMilestones; - renderMilestones(); - document - .querySelector('#button--addMilestone') - ?.addEventListener('click', () => { - let addFormElement; - let workOrderMilestoneDateStringElement; - let addCloseModalFunction; - function doAdd(submitEvent) { - if (submitEvent) { - submitEvent.preventDefault(); - } - const currentDateString = cityssm.dateToString(new Date()); - function _doAdd() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderMilestone`, addFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - processMilestoneResponse(responseJSON); - if (responseJSON.success) { - addCloseModalFunction(); - } - }); - } - const milestoneDateString = workOrderMilestoneDateStringElement.value; - if (milestoneDateString !== '' && - milestoneDateString < currentDateString) { - bulmaJS.confirm({ - title: 'Milestone Date in the Past', - message: 'Are you sure you want to create a milestone with a date in the past?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Create a Past Milestone', - callbackFunction: _doAdd - } - }); - } - else { - _doAdd(); - } - } - cityssm.openHtmlModal('workOrder-addMilestone', { - onshow(modalElement) { - ; - modalElement.querySelector('#milestoneAdd--workOrderId').value = workOrderId; - const milestoneTypeElement = modalElement.querySelector('#milestoneAdd--workOrderMilestoneTypeId'); - for (const milestoneType of exports.workOrderMilestoneTypes) { - const optionElement = document.createElement('option'); - optionElement.value = - milestoneType.workOrderMilestoneTypeId.toString(); - optionElement.textContent = milestoneType.workOrderMilestoneType; - milestoneTypeElement.append(optionElement); - } - workOrderMilestoneDateStringElement = modalElement.querySelector('#milestoneAdd--workOrderMilestoneDateString'); - workOrderMilestoneDateStringElement.valueAsDate = new Date(); - }, - onshown(modalElement, closeModalFunction) { - addCloseModalFunction = closeModalFunction; - los.initializeDatePickers(modalElement); - // los.initializeTimePickers(modalElement); - bulmaJS.toggleHtmlClipped(); - modalElement.querySelector('#milestoneAdd--workOrderMilestoneTypeId').focus(); - addFormElement = modalElement.querySelector('form'); - addFormElement.addEventListener('submit', doAdd); - const conflictingMilestonePanelElement = document.querySelector('#milestoneAdd--conflictingMilestonesPanel'); - workOrderMilestoneDateStringElement.addEventListener('change', () => { - refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement); - }); - refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#button--addMilestone').focus(); - } - }); - }); - } -})(); diff --git a/public-typescript/workOrderEdit/workOrderEdit.js b/public-typescript/workOrderEdit/workOrderEdit.js deleted file mode 100644 index f8fdc918..00000000 --- a/public-typescript/workOrderEdit/workOrderEdit.js +++ /dev/null @@ -1,525 +0,0 @@ -"use strict"; -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -(() => { - const los = exports.los; - const workOrderId = document.querySelector('#workOrderEdit--workOrderId').value; - const isCreate = workOrderId === ''; - const workOrderFormElement = document.querySelector('#form--workOrderEdit'); - los.initializeDatePickers(workOrderFormElement - .querySelector('#workOrderEdit--workOrderOpenDateString') - ?.closest('.field')); - los.initializeUnlockFieldButtons(workOrderFormElement); - function setUnsavedChanges() { - los.setUnsavedChanges(); - document - .querySelector("button[type='submit'][form='form--workOrderEdit']") - ?.classList.remove('is-light'); - } - function clearUnsavedChanges() { - los.clearUnsavedChanges(); - document - .querySelector("button[type='submit'][form='form--workOrderEdit']") - ?.classList.add('is-light'); - } - workOrderFormElement.addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/workOrders/${isCreate ? 'doCreateWorkOrder' : 'doUpdateWorkOrder'}`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - clearUnsavedChanges(); - if (isCreate) { - window.location.href = los.getWorkOrderURL(responseJSON.workOrderId, true); - } - else { - bulmaJS.alert({ - message: 'Work Order Updated Successfully', - contextualColorName: 'success' - }); - } - } - else { - bulmaJS.alert({ - title: 'Error Updating Work Order', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - }); - const inputElements = workOrderFormElement.querySelectorAll('input, select, textarea'); - for (const inputElement of inputElements) { - inputElement.addEventListener('change', setUnsavedChanges); - } - /* - * Work Order Options - */ - function doClose() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doCloseWorkOrder`, { - workOrderId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - clearUnsavedChanges(); - window.location.href = los.getWorkOrderURL(workOrderId); - } - else { - bulmaJS.alert({ - title: 'Error Closing Work Order', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrder`, { - workOrderId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - clearUnsavedChanges(); - window.location.href = `${los.urlPrefix}/workOrders`; - } - else { - bulmaJS.alert({ - title: 'Error Deleting Work Order', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - let workOrderMilestones; - document - .querySelector('#button--closeWorkOrder') - ?.addEventListener('click', () => { - const hasOpenMilestones = workOrderMilestones.some((milestone) => { - return !milestone.workOrderMilestoneCompletionDate; - }); - if (hasOpenMilestones) { - bulmaJS.alert({ - title: 'Outstanding Milestones', - message: `You cannot close a work order with outstanding milestones. - Either complete the outstanding milestones, or remove them from the work order.`, - contextualColorName: 'warning' - }); - /* - // Disable closing work orders with open milestones - bulmaJS.confirm({ - title: "Close Work Order with Outstanding Milestones", - message: - "Are you sure you want to close this work order with outstanding milestones?", - contextualColorName: "danger", - okButton: { - text: "Yes, Close Work Order", - callbackFunction: doClose - } - }); - */ - } - else { - bulmaJS.confirm({ - title: 'Close Work Order', - message: los.hasUnsavedChanges() - ? 'Are you sure you want to close this work order with unsaved changes?' - : 'Are you sure you want to close this work order?', - contextualColorName: los.hasUnsavedChanges() ? 'warning' : 'info', - okButton: { - text: 'Yes, Close Work Order', - callbackFunction: doClose - } - }); - } - }); - document - .querySelector('#button--deleteWorkOrder') - ?.addEventListener('click', (clickEvent) => { - clickEvent.preventDefault(); - bulmaJS.confirm({ - title: 'Delete Work Order', - message: 'Are you sure you want to delete this work order?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Work Order', - callbackFunction: doDelete - } - }); - }); - /* - * Related Lots - */ - if (!isCreate) { - //=include workOrderEditLots.js - } - /* - * Comments - */ - //=include workOrderEditComments.js - /* - * Milestones - */ - function clearPanelBlockElements(panelElement) { - for (const panelBlockElement of panelElement.querySelectorAll('.panel-block')) { - panelBlockElement.remove(); - } - } - function refreshConflictingMilestones(workOrderMilestoneDateString, targetPanelElement) { - // Clear panel-block elements - clearPanelBlockElements(targetPanelElement); - // eslint-disable-next-line no-unsanitized/method - targetPanelElement.insertAdjacentHTML('beforeend', `
    - ${los.getLoadingParagraphHTML('Loading conflicting milestones...')} -
    `); - cityssm.postJSON(`${los.urlPrefix}/workOrders/doGetWorkOrderMilestones`, { - workOrderMilestoneDateFilter: 'date', - workOrderMilestoneDateString - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - const workOrderMilestones = responseJSON.workOrderMilestones.filter((possibleMilestone) => { - return possibleMilestone.workOrderId.toString() !== workOrderId; - }); - clearPanelBlockElements(targetPanelElement); - for (const milestone of workOrderMilestones) { - targetPanelElement.insertAdjacentHTML('beforeend', `
    -
    -
    - ${cityssm.escapeHTML(milestone.workOrderMilestoneTime === 0 ? 'No Time' : milestone.workOrderMilestoneTimePeriodString ?? '')}
    - ${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')} -
    -
    - ${cityssm.escapeHTML(milestone.workOrderNumber ?? '')}
    - - ${cityssm.escapeHTML(milestone.workOrderDescription ?? '')} - -
    -
    -
    `); - } - if (workOrderMilestones.length === 0) { - targetPanelElement.insertAdjacentHTML('beforeend', `
    -
    -

    - There are no milestones on other work orders scheduled for - ${cityssm.escapeHTML(workOrderMilestoneDateString)}. -

    -
    -
    `); - } - }); - } - function processMilestoneResponse(rawResponseJSON) { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderMilestones = responseJSON.workOrderMilestones; - renderMilestones(); - } - else { - bulmaJS.alert({ - title: 'Error Reopening Milestone', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - } - function completeMilestone(clickEvent) { - clickEvent.preventDefault(); - const currentDateString = cityssm.dateToString(new Date()); - const workOrderMilestoneId = Number.parseInt(clickEvent.currentTarget.closest('.container--milestone').dataset.workOrderMilestoneId ?? '', 10); - const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { - return currentMilestone.workOrderMilestoneId === workOrderMilestoneId; - }); - function doComplete() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doCompleteWorkOrderMilestone`, { - workOrderId, - workOrderMilestoneId - }, processMilestoneResponse); - } - bulmaJS.confirm({ - title: 'Complete Milestone', - message: `Are you sure you want to complete this milestone? - ${workOrderMilestone.workOrderMilestoneDateString !== undefined && - workOrderMilestone.workOrderMilestoneDateString !== '' && - workOrderMilestone.workOrderMilestoneDateString > currentDateString - ? '
    Note that this milestone is expected to be completed in the future.' - : ''}`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Complete Milestone', - callbackFunction: doComplete - } - }); - } - function reopenMilestone(clickEvent) { - clickEvent.preventDefault(); - const workOrderMilestoneId = clickEvent.currentTarget.closest('.container--milestone').dataset.workOrderMilestoneId; - function doReopen() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doReopenWorkOrderMilestone`, { - workOrderId, - workOrderMilestoneId - }, processMilestoneResponse); - } - bulmaJS.confirm({ - title: 'Reopen Milestone', - message: 'Are you sure you want to remove the completion status from this milestone, and reopen it?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Reopen Milestone', - callbackFunction: doReopen - } - }); - } - function deleteMilestone(clickEvent) { - clickEvent.preventDefault(); - const workOrderMilestoneId = clickEvent.currentTarget.closest('.container--milestone').dataset.workOrderMilestoneId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrderMilestone`, { - workOrderMilestoneId, - workOrderId - }, processMilestoneResponse); - } - bulmaJS.confirm({ - title: 'Delete Milestone', - message: 'Are you sure you want to delete this milestone?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Milestone', - callbackFunction: doDelete - } - }); - } - function editMilestone(clickEvent) { - clickEvent.preventDefault(); - const workOrderMilestoneId = Number.parseInt(clickEvent.currentTarget.closest('.container--milestone').dataset.workOrderMilestoneId ?? '', 10); - const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { - return currentMilestone.workOrderMilestoneId === workOrderMilestoneId; - }); - let editCloseModalFunction; - let workOrderMilestoneDateStringElement; - function doEdit(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/workOrders/doUpdateWorkOrderMilestone`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - processMilestoneResponse(responseJSON); - if (responseJSON.success) { - editCloseModalFunction(); - } - }); - } - cityssm.openHtmlModal('workOrder-editMilestone', { - onshow(modalElement) { - ; - modalElement.querySelector('#milestoneEdit--workOrderId').value = workOrderId; - modalElement.querySelector('#milestoneEdit--workOrderMilestoneId').value = workOrderMilestone.workOrderMilestoneId?.toString() ?? ''; - const milestoneTypeElement = modalElement.querySelector('#milestoneEdit--workOrderMilestoneTypeId'); - let milestoneTypeFound = false; - for (const milestoneType of exports.workOrderMilestoneTypes) { - const optionElement = document.createElement('option'); - optionElement.value = - milestoneType.workOrderMilestoneTypeId.toString(); - optionElement.textContent = milestoneType.workOrderMilestoneType; - if (milestoneType.workOrderMilestoneTypeId === - workOrderMilestone.workOrderMilestoneTypeId) { - optionElement.selected = true; - milestoneTypeFound = true; - } - milestoneTypeElement.append(optionElement); - } - if (!milestoneTypeFound && - workOrderMilestone.workOrderMilestoneTypeId) { - const optionElement = document.createElement('option'); - optionElement.value = - workOrderMilestone.workOrderMilestoneTypeId.toString(); - optionElement.textContent = - workOrderMilestone.workOrderMilestoneType ?? ''; - optionElement.selected = true; - milestoneTypeElement.append(optionElement); - } - workOrderMilestoneDateStringElement = modalElement.querySelector('#milestoneEdit--workOrderMilestoneDateString'); - workOrderMilestoneDateStringElement.value = - workOrderMilestone.workOrderMilestoneDateString ?? ''; - if (workOrderMilestone.workOrderMilestoneTime) { - ; - modalElement.querySelector('#milestoneEdit--workOrderMilestoneTimeString').value = workOrderMilestone.workOrderMilestoneTimeString ?? ''; - } - ; - modalElement.querySelector('#milestoneEdit--workOrderMilestoneDescription').value = workOrderMilestone.workOrderMilestoneDescription ?? ''; - }, - onshown(modalElement, closeModalFunction) { - editCloseModalFunction = closeModalFunction; - bulmaJS.toggleHtmlClipped(); - los.initializeDatePickers(modalElement); - // los.initializeTimePickers(modalElement); - modalElement.querySelector('form')?.addEventListener('submit', doEdit); - const conflictingMilestonePanelElement = document.querySelector('#milestoneEdit--conflictingMilestonesPanel'); - workOrderMilestoneDateStringElement.addEventListener('change', () => { - refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement); - }); - refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); - } - function renderMilestones() { - // Clear milestones panel - const milestonesPanelElement = document.querySelector('#panel--milestones'); - const panelBlockElementsToDelete = milestonesPanelElement.querySelectorAll('.panel-block'); - for (const panelBlockToDelete of panelBlockElementsToDelete) { - panelBlockToDelete.remove(); - } - for (const milestone of workOrderMilestones) { - const panelBlockElement = document.createElement('div'); - panelBlockElement.className = 'panel-block is-block container--milestone'; - panelBlockElement.dataset.workOrderMilestoneId = - milestone.workOrderMilestoneId?.toString(); - // eslint-disable-next-line no-unsanitized/property - panelBlockElement.innerHTML = `
    -
    - ${milestone.workOrderMilestoneCompletionDate - ? ` - - ` - : ``} -
    - ${milestone.workOrderMilestoneTypeId - ? `${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')}
    ` - : ''} - ${milestone.workOrderMilestoneDate === 0 - ? '(No Set Date)' - : milestone.workOrderMilestoneDateString} - ${milestone.workOrderMilestoneTime - ? ` ${milestone.workOrderMilestoneTimePeriodString}` - : ''}
    - - ${cityssm.escapeHTML(milestone.workOrderMilestoneDescription ?? '')} - -
    - -
    `; - panelBlockElement - .querySelector('.button--reopenMilestone') - ?.addEventListener('click', reopenMilestone); - panelBlockElement - .querySelector('.button--editMilestone') - ?.addEventListener('click', editMilestone); - panelBlockElement - .querySelector('.button--completeMilestone') - ?.addEventListener('click', completeMilestone); - panelBlockElement - .querySelector('.button--deleteMilestone') - ?.addEventListener('click', deleteMilestone); - milestonesPanelElement.append(panelBlockElement); - } - bulmaJS.init(milestonesPanelElement); - } - if (!isCreate) { - workOrderMilestones = - exports.workOrderMilestones; - delete exports.workOrderMilestones; - renderMilestones(); - document - .querySelector('#button--addMilestone') - ?.addEventListener('click', () => { - let addFormElement; - let workOrderMilestoneDateStringElement; - let addCloseModalFunction; - function doAdd(submitEvent) { - if (submitEvent) { - submitEvent.preventDefault(); - } - const currentDateString = cityssm.dateToString(new Date()); - function _doAdd() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderMilestone`, addFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - processMilestoneResponse(responseJSON); - if (responseJSON.success) { - addCloseModalFunction(); - } - }); - } - const milestoneDateString = workOrderMilestoneDateStringElement.value; - if (milestoneDateString !== '' && - milestoneDateString < currentDateString) { - bulmaJS.confirm({ - title: 'Milestone Date in the Past', - message: 'Are you sure you want to create a milestone with a date in the past?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Create a Past Milestone', - callbackFunction: _doAdd - } - }); - } - else { - _doAdd(); - } - } - cityssm.openHtmlModal('workOrder-addMilestone', { - onshow(modalElement) { - ; - modalElement.querySelector('#milestoneAdd--workOrderId').value = workOrderId; - const milestoneTypeElement = modalElement.querySelector('#milestoneAdd--workOrderMilestoneTypeId'); - for (const milestoneType of exports.workOrderMilestoneTypes) { - const optionElement = document.createElement('option'); - optionElement.value = - milestoneType.workOrderMilestoneTypeId.toString(); - optionElement.textContent = milestoneType.workOrderMilestoneType; - milestoneTypeElement.append(optionElement); - } - workOrderMilestoneDateStringElement = modalElement.querySelector('#milestoneAdd--workOrderMilestoneDateString'); - workOrderMilestoneDateStringElement.valueAsDate = new Date(); - }, - onshown(modalElement, closeModalFunction) { - addCloseModalFunction = closeModalFunction; - los.initializeDatePickers(modalElement); - // los.initializeTimePickers(modalElement); - bulmaJS.toggleHtmlClipped(); - modalElement.querySelector('#milestoneAdd--workOrderMilestoneTypeId').focus(); - addFormElement = modalElement.querySelector('form'); - addFormElement.addEventListener('submit', doAdd); - const conflictingMilestonePanelElement = document.querySelector('#milestoneAdd--conflictingMilestonesPanel'); - workOrderMilestoneDateStringElement.addEventListener('change', () => { - refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement); - }); - refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#button--addMilestone').focus(); - } - }); - }); - } -})(); diff --git a/public-typescript/workOrderEdit/workOrderEdit.ts b/public-typescript/workOrderEdit/workOrderEdit.ts deleted file mode 100644 index de6f0db2..00000000 --- a/public-typescript/workOrderEdit/workOrderEdit.ts +++ /dev/null @@ -1,826 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ - -import type { BulmaJS } from '@cityssm/bulma-js/types.js' -import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' - -import type { LOS } from '../../types/globalTypes.js' -import type { WorkOrderMilestone, WorkOrderMilestoneType } from '../../types/recordTypes.js' - -declare const cityssm: cityssmGlobal -declare const bulmaJS: BulmaJS - -declare const exports: Record -;(() => { - const los = exports.los as LOS - - const workOrderId = ( - document.querySelector('#workOrderEdit--workOrderId') as HTMLInputElement - ).value - - const isCreate = workOrderId === '' - - const workOrderFormElement = document.querySelector( - '#form--workOrderEdit' - ) as HTMLFormElement - - los.initializeDatePickers( - workOrderFormElement - .querySelector('#workOrderEdit--workOrderOpenDateString') - ?.closest('.field') as HTMLElement - ) - los.initializeUnlockFieldButtons(workOrderFormElement) - - function setUnsavedChanges(): void { - los.setUnsavedChanges() - document - .querySelector("button[type='submit'][form='form--workOrderEdit']") - ?.classList.remove('is-light') - } - - function clearUnsavedChanges(): void { - los.clearUnsavedChanges() - document - .querySelector("button[type='submit'][form='form--workOrderEdit']") - ?.classList.add('is-light') - } - - workOrderFormElement.addEventListener('submit', (submitEvent) => { - submitEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/workOrders/${isCreate ? 'doCreateWorkOrder' : 'doUpdateWorkOrder'}`, - submitEvent.currentTarget, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - workOrderId?: number - errorMessage?: string - } - - if (responseJSON.success) { - clearUnsavedChanges() - - if (isCreate) { - window.location.href = los.getWorkOrderURL( - responseJSON.workOrderId, - true - ) - } else { - bulmaJS.alert({ - message: 'Work Order Updated Successfully', - contextualColorName: 'success' - }) - } - } else { - bulmaJS.alert({ - title: 'Error Updating Work Order', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - }) - - const inputElements: NodeListOf< - HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement - > = workOrderFormElement.querySelectorAll('input, select, textarea') - - for (const inputElement of inputElements) { - inputElement.addEventListener('change', setUnsavedChanges) - } - - /* - * Work Order Options - */ - - function doClose(): void { - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doCloseWorkOrder`, - { - workOrderId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - } - - if (responseJSON.success) { - clearUnsavedChanges() - window.location.href = los.getWorkOrderURL(workOrderId) - } else { - bulmaJS.alert({ - title: 'Error Closing Work Order', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doDeleteWorkOrder`, - { - workOrderId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - } - - if (responseJSON.success) { - clearUnsavedChanges() - window.location.href = `${los.urlPrefix}/workOrders` - } else { - bulmaJS.alert({ - title: 'Error Deleting Work Order', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - let workOrderMilestones: WorkOrderMilestone[] - - document - .querySelector('#button--closeWorkOrder') - ?.addEventListener('click', () => { - const hasOpenMilestones = workOrderMilestones.some((milestone) => { - return !milestone.workOrderMilestoneCompletionDate - }) - - if (hasOpenMilestones) { - bulmaJS.alert({ - title: 'Outstanding Milestones', - message: `You cannot close a work order with outstanding milestones. - Either complete the outstanding milestones, or remove them from the work order.`, - contextualColorName: 'warning' - }) - - /* - // Disable closing work orders with open milestones - bulmaJS.confirm({ - title: "Close Work Order with Outstanding Milestones", - message: - "Are you sure you want to close this work order with outstanding milestones?", - contextualColorName: "danger", - okButton: { - text: "Yes, Close Work Order", - callbackFunction: doClose - } - }); - */ - } else { - bulmaJS.confirm({ - title: 'Close Work Order', - message: los.hasUnsavedChanges() - ? 'Are you sure you want to close this work order with unsaved changes?' - : 'Are you sure you want to close this work order?', - contextualColorName: los.hasUnsavedChanges() ? 'warning' : 'info', - okButton: { - text: 'Yes, Close Work Order', - callbackFunction: doClose - } - }) - } - }) - - document - .querySelector('#button--deleteWorkOrder') - ?.addEventListener('click', (clickEvent: Event) => { - clickEvent.preventDefault() - - bulmaJS.confirm({ - title: 'Delete Work Order', - message: 'Are you sure you want to delete this work order?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Work Order', - callbackFunction: doDelete - } - }) - }) - - /* - * Related Lots - */ - - if (!isCreate) { - //=include workOrderEditLots.js - } - - /* - * Comments - */ - - //=include workOrderEditComments.js - - /* - * Milestones - */ - - function clearPanelBlockElements(panelElement: HTMLElement): void { - for (const panelBlockElement of panelElement.querySelectorAll( - '.panel-block' - )) { - panelBlockElement.remove() - } - } - - function refreshConflictingMilestones( - workOrderMilestoneDateString: string, - targetPanelElement: HTMLElement - ): void { - // Clear panel-block elements - clearPanelBlockElements(targetPanelElement) - - // eslint-disable-next-line no-unsanitized/method - targetPanelElement.insertAdjacentHTML( - 'beforeend', - `
    - ${los.getLoadingParagraphHTML('Loading conflicting milestones...')} -
    ` - ) - - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doGetWorkOrderMilestones`, - { - workOrderMilestoneDateFilter: 'date', - workOrderMilestoneDateString - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - workOrderMilestones: WorkOrderMilestone[] - } - - const workOrderMilestones = responseJSON.workOrderMilestones.filter( - (possibleMilestone) => { - return possibleMilestone.workOrderId.toString() !== workOrderId - } - ) - - clearPanelBlockElements(targetPanelElement) - - for (const milestone of workOrderMilestones) { - targetPanelElement.insertAdjacentHTML( - 'beforeend', - `
    -
    -
    - ${cityssm.escapeHTML(milestone.workOrderMilestoneTime === 0 ? 'No Time' : milestone.workOrderMilestoneTimePeriodString ?? '')}
    - ${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')} -
    -
    - ${cityssm.escapeHTML(milestone.workOrderNumber ?? '')}
    - - ${cityssm.escapeHTML(milestone.workOrderDescription ?? '')} - -
    -
    -
    ` - ) - } - - if (workOrderMilestones.length === 0) { - targetPanelElement.insertAdjacentHTML( - 'beforeend', - `
    -
    -

    - There are no milestones on other work orders scheduled for - ${cityssm.escapeHTML(workOrderMilestoneDateString)}. -

    -
    -
    ` - ) - } - } - ) - } - - function processMilestoneResponse(rawResponseJSON: unknown): void { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - workOrderMilestones: WorkOrderMilestone[] - } - - if (responseJSON.success) { - workOrderMilestones = responseJSON.workOrderMilestones - renderMilestones() - } else { - bulmaJS.alert({ - title: 'Error Reopening Milestone', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - - function completeMilestone(clickEvent: Event): void { - clickEvent.preventDefault() - - const currentDateString = cityssm.dateToString(new Date()) - - const workOrderMilestoneId = Number.parseInt( - ( - (clickEvent.currentTarget as HTMLElement).closest( - '.container--milestone' - ) as HTMLElement - ).dataset.workOrderMilestoneId ?? '', - 10 - ) - - const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { - return currentMilestone.workOrderMilestoneId === workOrderMilestoneId - }) as WorkOrderMilestone - - function doComplete(): void { - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doCompleteWorkOrderMilestone`, - { - workOrderId, - workOrderMilestoneId - }, - processMilestoneResponse - ) - } - - bulmaJS.confirm({ - title: 'Complete Milestone', - message: `Are you sure you want to complete this milestone? - ${ - workOrderMilestone.workOrderMilestoneDateString !== undefined && - workOrderMilestone.workOrderMilestoneDateString !== '' && - workOrderMilestone.workOrderMilestoneDateString > currentDateString - ? '
    Note that this milestone is expected to be completed in the future.' - : '' - }`, - messageIsHtml: true, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Complete Milestone', - callbackFunction: doComplete - } - }) - } - - function reopenMilestone(clickEvent: Event): void { - clickEvent.preventDefault() - - const workOrderMilestoneId = ( - (clickEvent.currentTarget as HTMLElement).closest( - '.container--milestone' - ) as HTMLElement - ).dataset.workOrderMilestoneId - - function doReopen(): void { - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doReopenWorkOrderMilestone`, - { - workOrderId, - workOrderMilestoneId - }, - processMilestoneResponse - ) - } - - bulmaJS.confirm({ - title: 'Reopen Milestone', - message: - 'Are you sure you want to remove the completion status from this milestone, and reopen it?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Reopen Milestone', - callbackFunction: doReopen - } - }) - } - - function deleteMilestone(clickEvent: Event): void { - clickEvent.preventDefault() - - const workOrderMilestoneId = ( - (clickEvent.currentTarget as HTMLElement).closest( - '.container--milestone' - ) as HTMLElement - ).dataset.workOrderMilestoneId - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doDeleteWorkOrderMilestone`, - { - workOrderMilestoneId, - workOrderId - }, - processMilestoneResponse - ) - } - - bulmaJS.confirm({ - title: 'Delete Milestone', - message: 'Are you sure you want to delete this milestone?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Milestone', - callbackFunction: doDelete - } - }) - } - - function editMilestone(clickEvent: Event): void { - clickEvent.preventDefault() - - const workOrderMilestoneId = Number.parseInt( - ( - (clickEvent.currentTarget as HTMLElement).closest( - '.container--milestone' - ) as HTMLElement - ).dataset.workOrderMilestoneId ?? '', - 10 - ) - - const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { - return currentMilestone.workOrderMilestoneId === workOrderMilestoneId - }) as WorkOrderMilestone - - let editCloseModalFunction: () => void - let workOrderMilestoneDateStringElement: HTMLInputElement - - function doEdit(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doUpdateWorkOrderMilestone`, - submitEvent.currentTarget, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - workOrderMilestones?: WorkOrderMilestone[] - } - - processMilestoneResponse(responseJSON) - if (responseJSON.success) { - editCloseModalFunction() - } - } - ) - } - - cityssm.openHtmlModal('workOrder-editMilestone', { - onshow(modalElement) { - ;( - modalElement.querySelector( - '#milestoneEdit--workOrderId' - ) as HTMLInputElement - ).value = workOrderId - ;( - modalElement.querySelector( - '#milestoneEdit--workOrderMilestoneId' - ) as HTMLInputElement - ).value = workOrderMilestone.workOrderMilestoneId?.toString() ?? '' - - const milestoneTypeElement = modalElement.querySelector( - '#milestoneEdit--workOrderMilestoneTypeId' - ) as HTMLSelectElement - - let milestoneTypeFound = false - - for (const milestoneType of exports.workOrderMilestoneTypes as WorkOrderMilestoneType[]) { - const optionElement = document.createElement('option') - - optionElement.value = - milestoneType.workOrderMilestoneTypeId.toString() - optionElement.textContent = milestoneType.workOrderMilestoneType - - if ( - milestoneType.workOrderMilestoneTypeId === - workOrderMilestone.workOrderMilestoneTypeId - ) { - optionElement.selected = true - milestoneTypeFound = true - } - - milestoneTypeElement.append(optionElement) - } - - if ( - !milestoneTypeFound && - workOrderMilestone.workOrderMilestoneTypeId - ) { - const optionElement = document.createElement('option') - - optionElement.value = - workOrderMilestone.workOrderMilestoneTypeId.toString() - - optionElement.textContent = - workOrderMilestone.workOrderMilestoneType ?? '' - - optionElement.selected = true - - milestoneTypeElement.append(optionElement) - } - - workOrderMilestoneDateStringElement = modalElement.querySelector( - '#milestoneEdit--workOrderMilestoneDateString' - ) as HTMLInputElement - - workOrderMilestoneDateStringElement.value = - workOrderMilestone.workOrderMilestoneDateString ?? '' - - if (workOrderMilestone.workOrderMilestoneTime) { - ;( - modalElement.querySelector( - '#milestoneEdit--workOrderMilestoneTimeString' - ) as HTMLInputElement - ).value = workOrderMilestone.workOrderMilestoneTimeString ?? '' - } - - ;( - modalElement.querySelector( - '#milestoneEdit--workOrderMilestoneDescription' - ) as HTMLTextAreaElement - ).value = workOrderMilestone.workOrderMilestoneDescription ?? '' - }, - onshown(modalElement, closeModalFunction) { - editCloseModalFunction = closeModalFunction - - bulmaJS.toggleHtmlClipped() - - los.initializeDatePickers(modalElement) - // los.initializeTimePickers(modalElement); - modalElement.querySelector('form')?.addEventListener('submit', doEdit) - - const conflictingMilestonePanelElement = document.querySelector( - '#milestoneEdit--conflictingMilestonesPanel' - ) as HTMLElement - - workOrderMilestoneDateStringElement.addEventListener('change', () => { - refreshConflictingMilestones( - workOrderMilestoneDateStringElement.value, - conflictingMilestonePanelElement - ) - }) - - refreshConflictingMilestones( - workOrderMilestoneDateStringElement.value, - conflictingMilestonePanelElement - ) - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - } - }) - } - - function renderMilestones(): void { - // Clear milestones panel - const milestonesPanelElement = document.querySelector( - '#panel--milestones' - ) as HTMLElement - - const panelBlockElementsToDelete = - milestonesPanelElement.querySelectorAll('.panel-block') - - for (const panelBlockToDelete of panelBlockElementsToDelete) { - panelBlockToDelete.remove() - } - - for (const milestone of workOrderMilestones) { - const panelBlockElement = document.createElement('div') - panelBlockElement.className = 'panel-block is-block container--milestone' - - panelBlockElement.dataset.workOrderMilestoneId = - milestone.workOrderMilestoneId?.toString() - - // eslint-disable-next-line no-unsanitized/property - panelBlockElement.innerHTML = `
    -
    - ${ - milestone.workOrderMilestoneCompletionDate - ? ` - - ` - : `` - } -
    - ${ - milestone.workOrderMilestoneTypeId - ? `${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')}
    ` - : '' - } - ${ - milestone.workOrderMilestoneDate === 0 - ? '(No Set Date)' - : milestone.workOrderMilestoneDateString - } - ${ - milestone.workOrderMilestoneTime - ? ` ${milestone.workOrderMilestoneTimePeriodString}` - : '' - }
    - - ${cityssm.escapeHTML(milestone.workOrderMilestoneDescription ?? '')} - -
    - -
    ` - - panelBlockElement - .querySelector('.button--reopenMilestone') - ?.addEventListener('click', reopenMilestone) - panelBlockElement - .querySelector('.button--editMilestone') - ?.addEventListener('click', editMilestone) - - panelBlockElement - .querySelector('.button--completeMilestone') - ?.addEventListener('click', completeMilestone) - - panelBlockElement - .querySelector('.button--deleteMilestone') - ?.addEventListener('click', deleteMilestone) - - milestonesPanelElement.append(panelBlockElement) - } - - bulmaJS.init(milestonesPanelElement) - } - - if (!isCreate) { - workOrderMilestones = - exports.workOrderMilestones as WorkOrderMilestone[] - delete exports.workOrderMilestones - - renderMilestones() - - document - .querySelector('#button--addMilestone') - ?.addEventListener('click', () => { - let addFormElement: HTMLFormElement - let workOrderMilestoneDateStringElement: HTMLInputElement - let addCloseModalFunction: () => void - - function doAdd(submitEvent: SubmitEvent): void { - if (submitEvent) { - submitEvent.preventDefault() - } - - const currentDateString = cityssm.dateToString(new Date()) - - function _doAdd(): void { - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doAddWorkOrderMilestone`, - addFormElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - workOrderMilestones?: WorkOrderMilestone[] - } - - processMilestoneResponse(responseJSON) - - if (responseJSON.success) { - addCloseModalFunction() - } - } - ) - } - - const milestoneDateString = workOrderMilestoneDateStringElement.value - - if ( - milestoneDateString !== '' && - milestoneDateString < currentDateString - ) { - bulmaJS.confirm({ - title: 'Milestone Date in the Past', - message: - 'Are you sure you want to create a milestone with a date in the past?', - contextualColorName: 'warning', - okButton: { - text: 'Yes, Create a Past Milestone', - callbackFunction: _doAdd - } - }) - } else { - _doAdd() - } - } - - cityssm.openHtmlModal('workOrder-addMilestone', { - onshow(modalElement) { - ;( - modalElement.querySelector( - '#milestoneAdd--workOrderId' - ) as HTMLInputElement - ).value = workOrderId - - const milestoneTypeElement = modalElement.querySelector( - '#milestoneAdd--workOrderMilestoneTypeId' - ) as HTMLSelectElement - - for (const milestoneType of exports.workOrderMilestoneTypes as WorkOrderMilestoneType[]) { - const optionElement = document.createElement('option') - - optionElement.value = - milestoneType.workOrderMilestoneTypeId.toString() - optionElement.textContent = milestoneType.workOrderMilestoneType - - milestoneTypeElement.append(optionElement) - } - - workOrderMilestoneDateStringElement = modalElement.querySelector( - '#milestoneAdd--workOrderMilestoneDateString' - ) as HTMLInputElement - - workOrderMilestoneDateStringElement.valueAsDate = new Date() - }, - onshown(modalElement, closeModalFunction) { - addCloseModalFunction = closeModalFunction - - los.initializeDatePickers(modalElement) - // los.initializeTimePickers(modalElement); - - bulmaJS.toggleHtmlClipped() - ;( - modalElement.querySelector( - '#milestoneAdd--workOrderMilestoneTypeId' - ) as HTMLSelectElement - ).focus() - - addFormElement = modalElement.querySelector( - 'form' - ) as HTMLFormElement - addFormElement.addEventListener('submit', doAdd) - - const conflictingMilestonePanelElement = document.querySelector( - '#milestoneAdd--conflictingMilestonesPanel' - ) as HTMLElement - - workOrderMilestoneDateStringElement.addEventListener( - 'change', - () => { - refreshConflictingMilestones( - workOrderMilestoneDateStringElement.value, - conflictingMilestonePanelElement - ) - } - ) - - refreshConflictingMilestones( - workOrderMilestoneDateStringElement.value, - conflictingMilestonePanelElement - ) - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - ;( - document.querySelector( - '#button--addMilestone' - ) as HTMLButtonElement - ).focus() - } - }) - }) - } -})() diff --git a/public-typescript/workOrderEdit/workOrderEditComments.d.ts b/public-typescript/workOrderEdit/workOrderEditComments.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/public-typescript/workOrderEdit/workOrderEditComments.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/public-typescript/workOrderEdit/workOrderEditComments.js b/public-typescript/workOrderEdit/workOrderEditComments.js deleted file mode 100644 index aa40731a..00000000 --- a/public-typescript/workOrderEdit/workOrderEditComments.js +++ /dev/null @@ -1,182 +0,0 @@ -"use strict"; -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -let workOrderComments = exports.workOrderComments; -delete exports.workOrderComments; -function openEditWorkOrderComment(clickEvent) { - const workOrderCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .workOrderCommentId ?? '', 10); - const workOrderComment = workOrderComments.find((currentComment) => { - return currentComment.workOrderCommentId === workOrderCommentId; - }); - let editFormElement; - let editCloseModalFunction; - function editComment(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/workOrders/doUpdateWorkOrderComment`, editFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderComments = responseJSON.workOrderComments; - editCloseModalFunction(); - renderWorkOrderComments(); - } - else { - bulmaJS.alert({ - title: 'Error Updating Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('workOrder-editComment', { - onshow(modalElement) { - ; - modalElement.querySelector('#workOrderCommentEdit--workOrderId').value = workOrderId; - modalElement.querySelector('#workOrderCommentEdit--workOrderCommentId').value = workOrderCommentId.toString(); - modalElement.querySelector('#workOrderCommentEdit--workOrderComment').value = workOrderComment.workOrderComment ?? ''; - const workOrderCommentDateStringElement = modalElement.querySelector('#workOrderCommentEdit--workOrderCommentDateString'); - workOrderCommentDateStringElement.value = - workOrderComment.workOrderCommentDateString ?? ''; - const currentDateString = cityssm.dateToString(new Date()); - workOrderCommentDateStringElement.max = - workOrderComment.workOrderCommentDateString <= currentDateString - ? currentDateString - : workOrderComment.workOrderCommentDateString ?? ''; - modalElement.querySelector('#workOrderCommentEdit--workOrderCommentTimeString').value = workOrderComment.workOrderCommentTimeString ?? ''; - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - los.initializeDatePickers(modalElement); - modalElement.querySelector('#workOrderCommentEdit--workOrderComment').focus(); - editFormElement = modalElement.querySelector('form'); - editFormElement.addEventListener('submit', editComment); - editCloseModalFunction = closeModalFunction; - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); -} -function deleteWorkOrderComment(clickEvent) { - const workOrderCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset - .workOrderCommentId ?? '', 10); - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrderComment`, { - workOrderId, - workOrderCommentId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderComments = responseJSON.workOrderComments; - renderWorkOrderComments(); - } - else { - bulmaJS.alert({ - title: 'Error Removing Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: 'Remove Comment?', - message: 'Are you sure you want to remove this comment?', - okButton: { - text: 'Yes, Remove Comment', - callbackFunction: doDelete - }, - contextualColorName: 'warning' - }); -} -function renderWorkOrderComments() { - const containerElement = document.querySelector('#container--workOrderComments'); - if (workOrderComments.length === 0) { - containerElement.innerHTML = `
    -

    There are no comments to display.

    -
    `; - return; - } - const tableElement = document.createElement('table'); - tableElement.className = 'table is-fullwidth is-striped is-hoverable'; - tableElement.innerHTML = ` - Commentor - Comment Date - Comment - Options`; - for (const workOrderComment of workOrderComments) { - const tableRowElement = document.createElement('tr'); - tableRowElement.dataset.workOrderCommentId = - workOrderComment.workOrderCommentId?.toString(); - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` - ${cityssm.escapeHTML(workOrderComment.recordCreate_userName ?? '')} - - ${workOrderComment.workOrderCommentDateString} - ${workOrderComment.workOrderCommentTime === 0 - ? '' - : workOrderComment.workOrderCommentTimePeriodString} - - ${cityssm.escapeHTML(workOrderComment.workOrderComment ?? '')} - -
    - - -
    - `; - tableRowElement - .querySelector('.button--edit') - ?.addEventListener('click', openEditWorkOrderComment); - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteWorkOrderComment); - tableElement.querySelector('tbody')?.append(tableRowElement); - } - containerElement.innerHTML = ''; - containerElement.append(tableElement); -} -function openAddCommentModal() { - let addCommentCloseModalFunction; - function doAddComment(formEvent) { - formEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderComment`, formEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderComments = responseJSON.workOrderComments; - renderWorkOrderComments(); - addCommentCloseModalFunction(); - } - }); - } - cityssm.openHtmlModal('workOrder-addComment', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#workOrderCommentAdd--workOrderId').value = workOrderId; - modalElement - .querySelector('form') - ?.addEventListener('submit', doAddComment); - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped(); - addCommentCloseModalFunction = closeModalFunction; - modalElement.querySelector('#workOrderCommentAdd--workOrderComment').focus(); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#workOrderComments--add').focus(); - } - }); -} -document - .querySelector('#workOrderComments--add') - ?.addEventListener('click', openAddCommentModal); -if (!isCreate) { - renderWorkOrderComments(); -} diff --git a/public-typescript/workOrderEdit/workOrderEditComments.ts b/public-typescript/workOrderEdit/workOrderEditComments.ts deleted file mode 100644 index 5c689ce8..00000000 --- a/public-typescript/workOrderEdit/workOrderEditComments.ts +++ /dev/null @@ -1,295 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ - -import type { BulmaJS } from '@cityssm/bulma-js/types.js' -import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' - -import type { LOS } from '../../types/globalTypes.js' -import type { WorkOrderComment } from '../../types/recordTypes.js' - -declare const cityssm: cityssmGlobal -declare const bulmaJS: BulmaJS - -declare const exports: Record -declare const los: LOS - -declare const workOrderId: string -declare const isCreate: boolean - -let workOrderComments = - exports.workOrderComments as WorkOrderComment[] -delete exports.workOrderComments - -function openEditWorkOrderComment(clickEvent: Event): void { - const workOrderCommentId = Number.parseInt( - (clickEvent.currentTarget as HTMLElement).closest('tr')?.dataset - .workOrderCommentId ?? '', - 10 - ) - - const workOrderComment = workOrderComments.find((currentComment) => { - return currentComment.workOrderCommentId === workOrderCommentId - }) as WorkOrderComment - - let editFormElement: HTMLFormElement - let editCloseModalFunction: () => void - - function editComment(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doUpdateWorkOrderComment`, - editFormElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - workOrderComments: WorkOrderComment[] - } - - if (responseJSON.success) { - workOrderComments = responseJSON.workOrderComments - editCloseModalFunction() - renderWorkOrderComments() - } else { - bulmaJS.alert({ - title: 'Error Updating Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - cityssm.openHtmlModal('workOrder-editComment', { - onshow(modalElement) { - ;( - modalElement.querySelector( - '#workOrderCommentEdit--workOrderId' - ) as HTMLInputElement - ).value = workOrderId - ;( - modalElement.querySelector( - '#workOrderCommentEdit--workOrderCommentId' - ) as HTMLInputElement - ).value = workOrderCommentId.toString() - ;( - modalElement.querySelector( - '#workOrderCommentEdit--workOrderComment' - ) as HTMLInputElement - ).value = workOrderComment.workOrderComment ?? '' - - const workOrderCommentDateStringElement = modalElement.querySelector( - '#workOrderCommentEdit--workOrderCommentDateString' - ) as HTMLInputElement - - workOrderCommentDateStringElement.value = - workOrderComment.workOrderCommentDateString ?? '' - - const currentDateString = cityssm.dateToString(new Date()) - - workOrderCommentDateStringElement.max = - workOrderComment.workOrderCommentDateString! <= currentDateString - ? currentDateString - : workOrderComment.workOrderCommentDateString ?? '' - ;( - modalElement.querySelector( - '#workOrderCommentEdit--workOrderCommentTimeString' - ) as HTMLInputElement - ).value = workOrderComment.workOrderCommentTimeString ?? '' - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped() - - los.initializeDatePickers(modalElement) - ;( - modalElement.querySelector( - '#workOrderCommentEdit--workOrderComment' - ) as HTMLTextAreaElement - ).focus() - - editFormElement = modalElement.querySelector('form') as HTMLFormElement - editFormElement.addEventListener('submit', editComment) - - editCloseModalFunction = closeModalFunction - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - } - }) -} - -function deleteWorkOrderComment(clickEvent: Event): void { - const workOrderCommentId = Number.parseInt( - (clickEvent.currentTarget as HTMLElement).closest('tr')?.dataset - .workOrderCommentId ?? '', - 10 - ) - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doDeleteWorkOrderComment`, - { - workOrderId, - workOrderCommentId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - workOrderComments: WorkOrderComment[] - } - - if (responseJSON.success) { - workOrderComments = responseJSON.workOrderComments - renderWorkOrderComments() - } else { - bulmaJS.alert({ - title: 'Error Removing Comment', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - bulmaJS.confirm({ - title: 'Remove Comment?', - message: 'Are you sure you want to remove this comment?', - okButton: { - text: 'Yes, Remove Comment', - callbackFunction: doDelete - }, - contextualColorName: 'warning' - }) -} - -function renderWorkOrderComments(): void { - const containerElement = document.querySelector( - '#container--workOrderComments' - ) as HTMLElement - - if (workOrderComments.length === 0) { - containerElement.innerHTML = `
    -

    There are no comments to display.

    -
    ` - return - } - - const tableElement = document.createElement('table') - tableElement.className = 'table is-fullwidth is-striped is-hoverable' - tableElement.innerHTML = ` - Commentor - Comment Date - Comment - Options` - - for (const workOrderComment of workOrderComments) { - const tableRowElement = document.createElement('tr') - - tableRowElement.dataset.workOrderCommentId = - workOrderComment.workOrderCommentId?.toString() - - // eslint-disable-next-line no-unsanitized/property - tableRowElement.innerHTML = ` - ${cityssm.escapeHTML(workOrderComment.recordCreate_userName ?? '')} - - ${workOrderComment.workOrderCommentDateString} - ${ - workOrderComment.workOrderCommentTime === 0 - ? '' - : workOrderComment.workOrderCommentTimePeriodString - } - - ${cityssm.escapeHTML(workOrderComment.workOrderComment ?? '')} - -
    - - -
    - ` - - tableRowElement - .querySelector('.button--edit') - ?.addEventListener('click', openEditWorkOrderComment) - - tableRowElement - .querySelector('.button--delete') - ?.addEventListener('click', deleteWorkOrderComment) - - tableElement.querySelector('tbody')?.append(tableRowElement) - } - - containerElement.innerHTML = '' - containerElement.append(tableElement) -} - -function openAddCommentModal(): void { - let addCommentCloseModalFunction: () => void - - function doAddComment(formEvent: SubmitEvent): void { - formEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doAddWorkOrderComment`, - formEvent.currentTarget, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - workOrderComments: WorkOrderComment[] - } - - if (responseJSON.success) { - workOrderComments = responseJSON.workOrderComments - renderWorkOrderComments() - addCommentCloseModalFunction() - } - } - ) - } - - cityssm.openHtmlModal('workOrder-addComment', { - onshow(modalElement) { - los.populateAliases(modalElement) - ;( - modalElement.querySelector( - '#workOrderCommentAdd--workOrderId' - ) as HTMLInputElement - ).value = workOrderId - - modalElement - .querySelector('form') - ?.addEventListener('submit', doAddComment) - }, - onshown(modalElement, closeModalFunction) { - bulmaJS.toggleHtmlClipped() - addCommentCloseModalFunction = closeModalFunction - ;( - modalElement.querySelector( - '#workOrderCommentAdd--workOrderComment' - ) as HTMLTextAreaElement - ).focus() - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - ;( - document.querySelector('#workOrderComments--add') as HTMLButtonElement - ).focus() - } - }) -} - -document - .querySelector('#workOrderComments--add') - ?.addEventListener('click', openAddCommentModal) - -if (!isCreate) { - renderWorkOrderComments() -} diff --git a/public-typescript/workOrderEdit/workOrderEditLots.d.ts b/public-typescript/workOrderEdit/workOrderEditLots.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/public-typescript/workOrderEdit/workOrderEditLots.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/public-typescript/workOrderEdit/workOrderEditLots.js b/public-typescript/workOrderEdit/workOrderEditLots.js deleted file mode 100644 index 4b1f3ea1..00000000 --- a/public-typescript/workOrderEdit/workOrderEditLots.js +++ /dev/null @@ -1,552 +0,0 @@ -"use strict"; -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ -Object.defineProperty(exports, "__esModule", { value: true }); -let workOrderLots = exports.workOrderLots; -delete exports.workOrderLots; -let workOrderLotOccupancies = exports.workOrderLotOccupancies; -delete exports.workOrderLotOccupancies; -function deleteLotOccupancy(clickEvent) { - const lotOccupancyId = clickEvent.currentTarget.closest('.container--lotOccupancy').dataset.lotOccupancyId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrderLotOccupancy`, { - workOrderId, - lotOccupancyId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderLotOccupancies = responseJSON.workOrderLotOccupancies; - renderRelatedLotsAndOccupancies(); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Relationship', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Occupancy} Relationship`, - message: `Are you sure you want to remove the relationship to this ${los.escapedAliases.occupancy} record from this work order? Note that the record will remain.`, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Relationship', - callbackFunction: doDelete - } - }); -} -function addLot(lotId, callbackFunction) { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderLot`, { - workOrderId, - lotId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderLots = responseJSON.workOrderLots; - renderRelatedLotsAndOccupancies(); - } - else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Lot}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - if (callbackFunction !== undefined) { - callbackFunction(responseJSON.success); - } - }); -} -function addLotOccupancy(lotOccupancyId, callbackFunction) { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderLotOccupancy`, { - workOrderId, - lotOccupancyId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderLotOccupancies = responseJSON.workOrderLotOccupancies; - renderRelatedLotsAndOccupancies(); - } - else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Occupancy}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - if (callbackFunction !== undefined) { - callbackFunction(responseJSON.success); - } - }); -} -function addLotFromLotOccupancy(clickEvent) { - const lotId = clickEvent.currentTarget.dataset.lotId ?? ''; - addLot(lotId); -} -function renderRelatedOccupancies() { - const occupanciesContainerElement = document.querySelector('#container--lotOccupancies'); - document.querySelector(".tabs a[href='#relatedTab--lotOccupancies'] .tag").textContent = workOrderLotOccupancies.length.toString(); - if (workOrderLotOccupancies.length === 0) { - // eslint-disable-next-line no-unsanitized/property - occupanciesContainerElement.innerHTML = `
    -

    There are no ${los.escapedAliases.occupancies} associated with this work order.

    -
    `; - return; - } - // eslint-disable-next-line no-unsanitized/property - occupanciesContainerElement.innerHTML = ` - - - - - - - - - - -
    ${los.escapedAliases.Occupancy} Type${los.escapedAliases.Lot}${los.escapedAliases.OccupancyStartDate}End Date${los.escapedAliases.Occupants}
    `; - const currentDateString = cityssm.dateToString(new Date()); - for (const lotOccupancy of workOrderLotOccupancies) { - const rowElement = document.createElement('tr'); - rowElement.className = 'container--lotOccupancy'; - rowElement.dataset.lotOccupancyId = lotOccupancy.lotOccupancyId.toString(); - const isActive = !(lotOccupancy.occupancyEndDate && - lotOccupancy.occupancyEndDateString < currentDateString); - const hasLotRecord = lotOccupancy.lotId && - workOrderLots.some((lot) => { - return lotOccupancy.lotId === lot.lotId; - }); - // eslint-disable-next-line no-unsanitized/property - rowElement.innerHTML = ` - ${isActive - ? `` - : ``} - - - ${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')} -
    - #${lotOccupancy.lotOccupancyId} - `; - if (lotOccupancy.lotId) { - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML('beforeend', ` - ${cityssm.escapeHTML(lotOccupancy.lotName ?? '')} - ${hasLotRecord - ? '' - : ` `} - `); - } - else { - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML('beforeend', `(No ${los.escapedAliases.Lot})`); - } - let occupantsHTML = ''; - for (const occupant of lotOccupancy.lotOccupancyOccupants) { - occupantsHTML += `
  • - - - - ${cityssm.escapeHTML(occupant.occupantName ?? '')} - ${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')} -
  • `; - } - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML('beforeend', ` - ${lotOccupancy.occupancyStartDateString} - - ${lotOccupancy.occupancyEndDate - ? lotOccupancy.occupancyEndDateString - : '(No End Date)'} - - ${lotOccupancy.lotOccupancyOccupants.length === 0 - ? `(No ${los.escapedAliases.Occupants})` - : `
      ${occupantsHTML}
    `} - - - `); - rowElement - .querySelector('.button--addLot') - ?.addEventListener('click', addLotFromLotOccupancy); - rowElement - .querySelector('.button--deleteLotOccupancy') - ?.addEventListener('click', deleteLotOccupancy); - occupanciesContainerElement.querySelector('tbody')?.append(rowElement); - } -} -function openEditLotStatus(clickEvent) { - const lotId = Number.parseInt(clickEvent.currentTarget.closest('.container--lot').dataset.lotId ?? '', 10); - const lot = workOrderLots.find((possibleLot) => { - return possibleLot.lotId === lotId; - }); - let editCloseModalFunction; - function doUpdateLotStatus(submitEvent) { - submitEvent.preventDefault(); - cityssm.postJSON(`${los.urlPrefix}/workOrders/doUpdateLotStatus`, submitEvent.currentTarget, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderLots = responseJSON.workOrderLots; - renderRelatedLotsAndOccupancies(); - editCloseModalFunction(); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Relationship', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - cityssm.openHtmlModal('lot-editLotStatus', { - onshow(modalElement) { - los.populateAliases(modalElement); - modalElement.querySelector('#lotStatusEdit--lotId').value = lotId.toString(); - modalElement.querySelector('#lotStatusEdit--lotName').value = lot.lotName ?? ''; - const lotStatusElement = modalElement.querySelector('#lotStatusEdit--lotStatusId'); - let lotStatusFound = false; - for (const lotStatus of exports.lotStatuses) { - const optionElement = document.createElement('option'); - optionElement.value = lotStatus.lotStatusId.toString(); - optionElement.textContent = lotStatus.lotStatus; - if (lotStatus.lotStatusId === lot.lotStatusId) { - lotStatusFound = true; - } - lotStatusElement.append(optionElement); - } - if (!lotStatusFound && lot.lotStatusId) { - const optionElement = document.createElement('option'); - optionElement.value = lot.lotStatusId.toString(); - optionElement.textContent = lot.lotStatus ?? ''; - lotStatusElement.append(optionElement); - } - if (lot.lotStatusId) { - lotStatusElement.value = lot.lotStatusId.toString(); - } - // eslint-disable-next-line no-unsanitized/method - modalElement - .querySelector('form') - ?.insertAdjacentHTML('beforeend', ``); - }, - onshown(modalElement, closeModalFunction) { - editCloseModalFunction = closeModalFunction; - bulmaJS.toggleHtmlClipped(); - modalElement - .querySelector('form') - ?.addEventListener('submit', doUpdateLotStatus); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - } - }); -} -function deleteLot(clickEvent) { - const lotId = clickEvent.currentTarget.closest('.container--lot').dataset.lotId; - function doDelete() { - cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrderLot`, { - workOrderId, - lotId - }, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.success) { - workOrderLots = responseJSON.workOrderLots; - renderRelatedLotsAndOccupancies(); - } - else { - bulmaJS.alert({ - title: 'Error Deleting Relationship', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }); - } - }); - } - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Occupancy} Relationship`, - message: `Are you sure you want to remove the relationship to this ${los.escapedAliases.occupancy} record from this work order? Note that the record will remain.`, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Relationship', - callbackFunction: doDelete - } - }); -} -function renderRelatedLots() { - const lotsContainerElement = document.querySelector('#container--lots'); - document.querySelector(".tabs a[href='#relatedTab--lots'] .tag").textContent = workOrderLots.length.toString(); - if (workOrderLots.length === 0) { - // eslint-disable-next-line no-unsanitized/property - lotsContainerElement.innerHTML = `
    -

    There are no ${los.escapedAliases.lots} associated with this work order.

    -
    `; - return; - } - // eslint-disable-next-line no-unsanitized/property - lotsContainerElement.innerHTML = ` - - - - - - - - -
    ${los.escapedAliases.Lot}${los.escapedAliases.Map}${los.escapedAliases.Lot} TypeStatus
    `; - for (const lot of workOrderLots) { - const rowElement = document.createElement('tr'); - rowElement.className = 'container--lot'; - rowElement.dataset.lotId = lot.lotId.toString(); - // eslint-disable-next-line no-unsanitized/property - rowElement.innerHTML = ` - - ${cityssm.escapeHTML(lot.lotName ?? '')} - - - ${cityssm.escapeHTML(lot.mapName ?? '')} - - ${cityssm.escapeHTML(lot.lotType ?? '')} - - ${lot.lotStatusId - ? cityssm.escapeHTML(lot.lotStatus ?? '') - : '(No Status)'} - - - - `; - rowElement - .querySelector('.button--editLotStatus') - ?.addEventListener('click', openEditLotStatus); - rowElement - .querySelector('.button--deleteLot') - ?.addEventListener('click', deleteLot); - lotsContainerElement.querySelector('tbody')?.append(rowElement); - } -} -function renderRelatedLotsAndOccupancies() { - renderRelatedOccupancies(); - renderRelatedLots(); -} -renderRelatedLotsAndOccupancies(); -function doAddLotOccupancy(clickEvent) { - const rowElement = clickEvent.currentTarget.closest('tr'); - const lotOccupancyId = rowElement.dataset.lotOccupancyId ?? ''; - addLotOccupancy(lotOccupancyId, (success) => { - if (success) { - rowElement.remove(); - } - }); -} -document - .querySelector('#button--addLotOccupancy') - ?.addEventListener('click', () => { - let searchFormElement; - let searchResultsContainerElement; - function doSearch(event) { - if (event) { - event.preventDefault(); - } - // eslint-disable-next-line no-unsanitized/property - searchResultsContainerElement.innerHTML = - los.getLoadingParagraphHTML('Searching...'); - cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doSearchLotOccupancies`, searchFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.lotOccupancies.length === 0) { - searchResultsContainerElement.innerHTML = `
    -

    There are no records that meet the search criteria.

    -
    `; - return; - } - // eslint-disable-next-line no-unsanitized/property - searchResultsContainerElement.innerHTML = ` - - - - - - - - - -
    ${los.escapedAliases.Occupancy} Type${los.escapedAliases.Lot}${los.escapedAliases.OccupancyStartDate}End Date${los.escapedAliases.Occupants}
    `; - for (const lotOccupancy of responseJSON.lotOccupancies) { - const rowElement = document.createElement('tr'); - rowElement.className = 'container--lotOccupancy'; - rowElement.dataset.lotOccupancyId = - lotOccupancy.lotOccupancyId.toString(); - rowElement.innerHTML = ` - - - - ${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')} - `; - if (lotOccupancy.lotId) { - rowElement.insertAdjacentHTML('beforeend', `${cityssm.escapeHTML(lotOccupancy.lotName ?? '')}`); - } - else { - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML('beforeend', `(No ${los.escapedAliases.Lot})`); - } - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML('beforeend', ` - ${lotOccupancy.occupancyStartDateString} - - ${lotOccupancy.occupancyEndDate - ? lotOccupancy.occupancyEndDateString - : '(No End Date)'} - - ${lotOccupancy.lotOccupancyOccupants.length === 0 - ? ` - (No ${cityssm.escapeHTML(los.escapedAliases.Occupants)}) - ` - : cityssm.escapeHTML(`${lotOccupancy.lotOccupancyOccupants[0].occupantName} - ${lotOccupancy.lotOccupancyOccupants[0] - .occupantFamilyName}`) + - (lotOccupancy.lotOccupancyOccupants.length > 1 - ? ` plus - ${(lotOccupancy.lotOccupancyOccupants.length - 1).toString()}` - : '')}`); - rowElement - .querySelector('.button--addLotOccupancy') - ?.addEventListener('click', doAddLotOccupancy); - searchResultsContainerElement - .querySelector('tbody') - ?.append(rowElement); - } - }); - } - cityssm.openHtmlModal('workOrder-addLotOccupancy', { - onshow(modalElement) { - los.populateAliases(modalElement); - searchFormElement = modalElement.querySelector('form'); - searchResultsContainerElement = modalElement.querySelector('#resultsContainer--lotOccupancyAdd'); - modalElement.querySelector('#lotOccupancySearch--notWorkOrderId').value = workOrderId; - modalElement.querySelector('#lotOccupancySearch--occupancyEffectiveDateString').value = document.querySelector('#workOrderEdit--workOrderOpenDateString').value; - doSearch(); - }, - onshown(modalElement) { - bulmaJS.toggleHtmlClipped(); - const occupantNameElement = modalElement.querySelector('#lotOccupancySearch--occupantName'); - occupantNameElement.addEventListener('change', doSearch); - occupantNameElement.focus(); - modalElement.querySelector('#lotOccupancySearch--lotName').addEventListener('change', doSearch); - searchFormElement.addEventListener('submit', doSearch); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#button--addLotOccupancy').focus(); - } - }); -}); -function doAddLot(clickEvent) { - const rowElement = clickEvent.currentTarget.closest('tr'); - const lotId = rowElement.dataset.lotId ?? ''; - addLot(lotId, (success) => { - if (success) { - rowElement.remove(); - } - }); -} -document.querySelector('#button--addLot')?.addEventListener('click', () => { - let searchFormElement; - let searchResultsContainerElement; - function doSearch(event) { - if (event) { - event.preventDefault(); - } - // eslint-disable-next-line no-unsanitized/property - searchResultsContainerElement.innerHTML = - los.getLoadingParagraphHTML('Searching...'); - cityssm.postJSON(`${los.urlPrefix}/lots/doSearchLots`, searchFormElement, (rawResponseJSON) => { - const responseJSON = rawResponseJSON; - if (responseJSON.lots.length === 0) { - searchResultsContainerElement.innerHTML = `
    -

    There are no records that meet the search criteria.

    -
    `; - return; - } - // eslint-disable-next-line no-unsanitized/property - searchResultsContainerElement.innerHTML = ` - - - - - - - - -
    ${los.escapedAliases.Lot}${los.escapedAliases.Map}${los.escapedAliases.Lot} TypeStatus
    `; - for (const lot of responseJSON.lots) { - const rowElement = document.createElement('tr'); - rowElement.className = 'container--lot'; - rowElement.dataset.lotId = lot.lotId.toString(); - rowElement.innerHTML = ` - - - ${cityssm.escapeHTML(lot.lotName ?? '')} - - ${cityssm.escapeHTML(lot.mapName ?? '')} - - ${cityssm.escapeHTML(lot.lotType ?? '')} - - ${cityssm.escapeHTML(lot.lotStatus ?? '')} - `; - rowElement - .querySelector('.button--addLot') - ?.addEventListener('click', doAddLot); - searchResultsContainerElement - .querySelector('tbody') - ?.append(rowElement); - } - }); - } - cityssm.openHtmlModal('workOrder-addLot', { - onshow(modalElement) { - los.populateAliases(modalElement); - searchFormElement = modalElement.querySelector('form'); - searchResultsContainerElement = modalElement.querySelector('#resultsContainer--lotAdd'); - modalElement.querySelector('#lotSearch--notWorkOrderId').value = workOrderId; - const lotStatusElement = modalElement.querySelector('#lotSearch--lotStatusId'); - for (const lotStatus of exports.lotStatuses) { - const optionElement = document.createElement('option'); - optionElement.value = lotStatus.lotStatusId.toString(); - optionElement.textContent = lotStatus.lotStatus; - lotStatusElement.append(optionElement); - } - doSearch(); - }, - onshown(modalElement) { - bulmaJS.toggleHtmlClipped(); - const lotNameElement = modalElement.querySelector('#lotSearch--lotName'); - lotNameElement.addEventListener('change', doSearch); - lotNameElement.focus(); - modalElement - .querySelector('#lotSearch--lotStatusId') - ?.addEventListener('change', doSearch); - searchFormElement.addEventListener('submit', doSearch); - }, - onremoved() { - bulmaJS.toggleHtmlClipped(); - document.querySelector('#button--addLot').focus(); - } - }); -}); diff --git a/public-typescript/workOrderEdit/workOrderEditLots.ts b/public-typescript/workOrderEdit/workOrderEditLots.ts deleted file mode 100644 index 04bf8fcf..00000000 --- a/public-typescript/workOrderEdit/workOrderEditLots.ts +++ /dev/null @@ -1,847 +0,0 @@ -// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair -/* eslint-disable unicorn/prefer-module */ - -import type { BulmaJS } from '@cityssm/bulma-js/types.js' -import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' - -import type { LOS } from '../../types/globalTypes.js' -import type { Lot, LotOccupancy, LotStatus } from '../../types/recordTypes.js' - -declare const cityssm: cityssmGlobal -declare const bulmaJS: BulmaJS - -declare const exports: Record -declare const los: LOS - -declare const workOrderId: string - -let workOrderLots = exports.workOrderLots as Lot[] -delete exports.workOrderLots - -let workOrderLotOccupancies = exports.workOrderLotOccupancies as LotOccupancy[] -delete exports.workOrderLotOccupancies - -function deleteLotOccupancy(clickEvent: Event): void { - const lotOccupancyId = ( - (clickEvent.currentTarget as HTMLElement).closest( - '.container--lotOccupancy' - ) as HTMLElement - ).dataset.lotOccupancyId - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doDeleteWorkOrderLotOccupancy`, - { - workOrderId, - lotOccupancyId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - workOrderLotOccupancies: LotOccupancy[] - } - - if (responseJSON.success) { - workOrderLotOccupancies = responseJSON.workOrderLotOccupancies - renderRelatedLotsAndOccupancies() - } else { - bulmaJS.alert({ - title: 'Error Deleting Relationship', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Occupancy} Relationship`, - message: `Are you sure you want to remove the relationship to this ${los.escapedAliases.occupancy} record from this work order? Note that the record will remain.`, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Relationship', - callbackFunction: doDelete - } - }) -} - -function addLot( - lotId: number | string, - callbackFunction?: (success: boolean) => void -): void { - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doAddWorkOrderLot`, - { - workOrderId, - lotId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - workOrderLots: Lot[] - } - - if (responseJSON.success) { - workOrderLots = responseJSON.workOrderLots - renderRelatedLotsAndOccupancies() - } else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Lot}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - - if (callbackFunction !== undefined) { - callbackFunction(responseJSON.success) - } - } - ) -} - -function addLotOccupancy( - lotOccupancyId: number | string, - callbackFunction?: (success?: boolean) => void -): void { - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doAddWorkOrderLotOccupancy`, - { - workOrderId, - lotOccupancyId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - workOrderLotOccupancies: LotOccupancy[] - } - - if (responseJSON.success) { - workOrderLotOccupancies = responseJSON.workOrderLotOccupancies - renderRelatedLotsAndOccupancies() - } else { - bulmaJS.alert({ - title: `Error Adding ${los.escapedAliases.Occupancy}`, - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - - if (callbackFunction !== undefined) { - callbackFunction(responseJSON.success) - } - } - ) -} - -function addLotFromLotOccupancy(clickEvent: Event): void { - const lotId = (clickEvent.currentTarget as HTMLElement).dataset.lotId ?? '' - addLot(lotId) -} - -function renderRelatedOccupancies(): void { - const occupanciesContainerElement = document.querySelector( - '#container--lotOccupancies' - ) as HTMLElement - - ;( - document.querySelector( - ".tabs a[href='#relatedTab--lotOccupancies'] .tag" - ) as HTMLElement - ).textContent = workOrderLotOccupancies.length.toString() - - if (workOrderLotOccupancies.length === 0) { - // eslint-disable-next-line no-unsanitized/property - occupanciesContainerElement.innerHTML = `
    -

    There are no ${los.escapedAliases.occupancies} associated with this work order.

    -
    ` - - return - } - - // eslint-disable-next-line no-unsanitized/property - occupanciesContainerElement.innerHTML = ` - - - - - - - - - - -
    ${los.escapedAliases.Occupancy} Type${los.escapedAliases.Lot}${los.escapedAliases.OccupancyStartDate}End Date${los.escapedAliases.Occupants}
    ` - - const currentDateString = cityssm.dateToString(new Date()) - - for (const lotOccupancy of workOrderLotOccupancies) { - const rowElement = document.createElement('tr') - rowElement.className = 'container--lotOccupancy' - rowElement.dataset.lotOccupancyId = lotOccupancy.lotOccupancyId.toString() - - const isActive = !( - lotOccupancy.occupancyEndDate && - lotOccupancy.occupancyEndDateString! < currentDateString - ) - - const hasLotRecord = - lotOccupancy.lotId && - workOrderLots.some((lot) => { - return lotOccupancy.lotId === lot.lotId - }) - - // eslint-disable-next-line no-unsanitized/property - rowElement.innerHTML = ` - ${ - isActive - ? `` - : `` - } - - - ${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')} -
    - #${lotOccupancy.lotOccupancyId} - ` - - if (lotOccupancy.lotId) { - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML( - 'beforeend', - ` - ${cityssm.escapeHTML(lotOccupancy.lotName ?? '')} - ${ - hasLotRecord - ? '' - : ` ` - } - ` - ) - } else { - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML( - 'beforeend', - `(No ${los.escapedAliases.Lot})` - ) - } - - let occupantsHTML = '' - - for (const occupant of lotOccupancy.lotOccupancyOccupants!) { - occupantsHTML += `
  • - - - - ${cityssm.escapeHTML(occupant.occupantName ?? '')} - ${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')} -
  • ` - } - - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML( - 'beforeend', - ` - ${lotOccupancy.occupancyStartDateString} - - ${ - lotOccupancy.occupancyEndDate - ? lotOccupancy.occupancyEndDateString - : '(No End Date)' - } - - ${ - lotOccupancy.lotOccupancyOccupants!.length === 0 - ? `(No ${los.escapedAliases.Occupants})` - : `
      ${occupantsHTML}
    ` - } - - - ` - ) - - rowElement - .querySelector('.button--addLot') - ?.addEventListener('click', addLotFromLotOccupancy) - - rowElement - .querySelector('.button--deleteLotOccupancy') - ?.addEventListener('click', deleteLotOccupancy) - - occupanciesContainerElement.querySelector('tbody')?.append(rowElement) - } -} - -function openEditLotStatus(clickEvent: Event): void { - const lotId = Number.parseInt( - ( - (clickEvent.currentTarget as HTMLElement).closest( - '.container--lot' - ) as HTMLElement - ).dataset.lotId ?? '', - 10 - ) - - const lot = workOrderLots.find((possibleLot) => { - return possibleLot.lotId === lotId - }) as Lot - - let editCloseModalFunction: () => void - - function doUpdateLotStatus(submitEvent: SubmitEvent): void { - submitEvent.preventDefault() - - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doUpdateLotStatus`, - submitEvent.currentTarget, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - workOrderLots: Lot[] - } - - if (responseJSON.success) { - workOrderLots = responseJSON.workOrderLots - renderRelatedLotsAndOccupancies() - editCloseModalFunction() - } else { - bulmaJS.alert({ - title: 'Error Deleting Relationship', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - cityssm.openHtmlModal('lot-editLotStatus', { - onshow(modalElement) { - los.populateAliases(modalElement) - ;( - modalElement.querySelector('#lotStatusEdit--lotId') as HTMLInputElement - ).value = lotId.toString() - ;( - modalElement.querySelector( - '#lotStatusEdit--lotName' - ) as HTMLInputElement - ).value = lot.lotName ?? '' - - const lotStatusElement = modalElement.querySelector( - '#lotStatusEdit--lotStatusId' - ) as HTMLSelectElement - - let lotStatusFound = false - - for (const lotStatus of exports.lotStatuses as LotStatus[]) { - const optionElement = document.createElement('option') - optionElement.value = lotStatus.lotStatusId.toString() - optionElement.textContent = lotStatus.lotStatus - - if (lotStatus.lotStatusId === lot.lotStatusId) { - lotStatusFound = true - } - - lotStatusElement.append(optionElement) - } - - if (!lotStatusFound && lot.lotStatusId) { - const optionElement = document.createElement('option') - optionElement.value = lot.lotStatusId.toString() - optionElement.textContent = lot.lotStatus ?? '' - lotStatusElement.append(optionElement) - } - - if (lot.lotStatusId) { - lotStatusElement.value = lot.lotStatusId.toString() - } - - // eslint-disable-next-line no-unsanitized/method - modalElement - .querySelector('form') - ?.insertAdjacentHTML( - 'beforeend', - `` - ) - }, - onshown(modalElement, closeModalFunction) { - editCloseModalFunction = closeModalFunction - - bulmaJS.toggleHtmlClipped() - - modalElement - .querySelector('form') - ?.addEventListener('submit', doUpdateLotStatus) - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - } - }) -} - -function deleteLot(clickEvent: Event): void { - const lotId = ( - (clickEvent.currentTarget as HTMLElement).closest( - '.container--lot' - ) as HTMLElement - ).dataset.lotId - - function doDelete(): void { - cityssm.postJSON( - `${los.urlPrefix}/workOrders/doDeleteWorkOrderLot`, - { - workOrderId, - lotId - }, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - success: boolean - errorMessage?: string - workOrderLots: Lot[] - } - - if (responseJSON.success) { - workOrderLots = responseJSON.workOrderLots - renderRelatedLotsAndOccupancies() - } else { - bulmaJS.alert({ - title: 'Error Deleting Relationship', - message: responseJSON.errorMessage ?? '', - contextualColorName: 'danger' - }) - } - } - ) - } - - bulmaJS.confirm({ - title: `Delete ${los.escapedAliases.Occupancy} Relationship`, - message: `Are you sure you want to remove the relationship to this ${los.escapedAliases.occupancy} record from this work order? Note that the record will remain.`, - contextualColorName: 'warning', - okButton: { - text: 'Yes, Delete Relationship', - callbackFunction: doDelete - } - }) -} - -function renderRelatedLots(): void { - const lotsContainerElement = document.querySelector( - '#container--lots' - ) as HTMLElement - - ;( - document.querySelector( - ".tabs a[href='#relatedTab--lots'] .tag" - ) as HTMLElement - ).textContent = workOrderLots.length.toString() - - if (workOrderLots.length === 0) { - // eslint-disable-next-line no-unsanitized/property - lotsContainerElement.innerHTML = `
    -

    There are no ${los.escapedAliases.lots} associated with this work order.

    -
    ` - - return - } - - // eslint-disable-next-line no-unsanitized/property - lotsContainerElement.innerHTML = ` - - - - - - - - -
    ${los.escapedAliases.Lot}${los.escapedAliases.Map}${los.escapedAliases.Lot} TypeStatus
    ` - - for (const lot of workOrderLots) { - const rowElement = document.createElement('tr') - rowElement.className = 'container--lot' - - rowElement.dataset.lotId = lot.lotId.toString() - - // eslint-disable-next-line no-unsanitized/property - rowElement.innerHTML = ` - - ${cityssm.escapeHTML(lot.lotName ?? '')} - - - ${cityssm.escapeHTML(lot.mapName ?? '')} - - ${cityssm.escapeHTML(lot.lotType ?? '')} - - ${ - lot.lotStatusId - ? cityssm.escapeHTML(lot.lotStatus ?? '') - : '(No Status)' - } - - - - ` - - rowElement - .querySelector('.button--editLotStatus') - ?.addEventListener('click', openEditLotStatus) - - rowElement - .querySelector('.button--deleteLot') - ?.addEventListener('click', deleteLot) - - lotsContainerElement.querySelector('tbody')?.append(rowElement) - } -} - -function renderRelatedLotsAndOccupancies(): void { - renderRelatedOccupancies() - renderRelatedLots() -} - -renderRelatedLotsAndOccupancies() - -function doAddLotOccupancy(clickEvent: Event): void { - const rowElement = (clickEvent.currentTarget as HTMLElement).closest( - 'tr' - ) as HTMLTableRowElement - - const lotOccupancyId = rowElement.dataset.lotOccupancyId ?? '' - - addLotOccupancy(lotOccupancyId, (success) => { - if (success) { - rowElement.remove() - } - }) -} - -document - .querySelector('#button--addLotOccupancy') - ?.addEventListener('click', () => { - let searchFormElement: HTMLFormElement - let searchResultsContainerElement: HTMLElement - - function doSearch(event?: Event): void { - if (event) { - event.preventDefault() - } - - // eslint-disable-next-line no-unsanitized/property - searchResultsContainerElement.innerHTML = - los.getLoadingParagraphHTML('Searching...') - - cityssm.postJSON( - `${los.urlPrefix}/lotOccupancies/doSearchLotOccupancies`, - searchFormElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { - lotOccupancies: LotOccupancy[] - } - - if (responseJSON.lotOccupancies.length === 0) { - searchResultsContainerElement.innerHTML = `
    -

    There are no records that meet the search criteria.

    -
    ` - - return - } - - // eslint-disable-next-line no-unsanitized/property - searchResultsContainerElement.innerHTML = ` - - - - - - - - - -
    ${los.escapedAliases.Occupancy} Type${los.escapedAliases.Lot}${los.escapedAliases.OccupancyStartDate}End Date${los.escapedAliases.Occupants}
    ` - - for (const lotOccupancy of responseJSON.lotOccupancies) { - const rowElement = document.createElement('tr') - rowElement.className = 'container--lotOccupancy' - rowElement.dataset.lotOccupancyId = - lotOccupancy.lotOccupancyId.toString() - - rowElement.innerHTML = ` - - - - ${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')} - ` - - if (lotOccupancy.lotId) { - rowElement.insertAdjacentHTML( - 'beforeend', - `${cityssm.escapeHTML(lotOccupancy.lotName ?? '')}` - ) - } else { - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML( - 'beforeend', - `(No ${los.escapedAliases.Lot})` - ) - } - - // eslint-disable-next-line no-unsanitized/method - rowElement.insertAdjacentHTML( - 'beforeend', - ` - ${lotOccupancy.occupancyStartDateString} - - ${ - lotOccupancy.occupancyEndDate - ? lotOccupancy.occupancyEndDateString - : '(No End Date)' - } - - ${ - lotOccupancy.lotOccupancyOccupants!.length === 0 - ? ` - (No ${cityssm.escapeHTML( - los.escapedAliases.Occupants - )}) - ` - : cityssm.escapeHTML( - `${lotOccupancy.lotOccupancyOccupants![0].occupantName} - ${ - lotOccupancy.lotOccupancyOccupants![0] - .occupantFamilyName - }` - ) + - (lotOccupancy.lotOccupancyOccupants!.length > 1 - ? ` plus - ${( - lotOccupancy.lotOccupancyOccupants!.length - 1 - ).toString()}` - : '') - }` - ) - - rowElement - .querySelector('.button--addLotOccupancy') - ?.addEventListener('click', doAddLotOccupancy) - - searchResultsContainerElement - .querySelector('tbody') - ?.append(rowElement) - } - } - ) - } - - cityssm.openHtmlModal('workOrder-addLotOccupancy', { - onshow(modalElement) { - los.populateAliases(modalElement) - - searchFormElement = modalElement.querySelector( - 'form' - ) as HTMLFormElement - - searchResultsContainerElement = modalElement.querySelector( - '#resultsContainer--lotOccupancyAdd' - ) as HTMLElement - ;( - modalElement.querySelector( - '#lotOccupancySearch--notWorkOrderId' - ) as HTMLInputElement - ).value = workOrderId - ;( - modalElement.querySelector( - '#lotOccupancySearch--occupancyEffectiveDateString' - ) as HTMLInputElement - ).value = ( - document.querySelector( - '#workOrderEdit--workOrderOpenDateString' - ) as HTMLInputElement - ).value - - doSearch() - }, - onshown(modalElement) { - bulmaJS.toggleHtmlClipped() - - const occupantNameElement = modalElement.querySelector( - '#lotOccupancySearch--occupantName' - ) as HTMLInputElement - - occupantNameElement.addEventListener('change', doSearch) - occupantNameElement.focus() - ;( - modalElement.querySelector( - '#lotOccupancySearch--lotName' - ) as HTMLInputElement - ).addEventListener('change', doSearch) - - searchFormElement.addEventListener('submit', doSearch) - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - ;( - document.querySelector( - '#button--addLotOccupancy' - ) as HTMLButtonElement - ).focus() - } - }) - }) - -function doAddLot(clickEvent: Event): void { - const rowElement = (clickEvent.currentTarget as HTMLElement).closest( - 'tr' - ) as HTMLTableRowElement - - const lotId = rowElement.dataset.lotId ?? '' - - addLot(lotId, (success) => { - if (success) { - rowElement.remove() - } - }) -} - -document.querySelector('#button--addLot')?.addEventListener('click', () => { - let searchFormElement: HTMLFormElement - let searchResultsContainerElement: HTMLElement - - function doSearch(event?: Event): void { - if (event) { - event.preventDefault() - } - - // eslint-disable-next-line no-unsanitized/property - searchResultsContainerElement.innerHTML = - los.getLoadingParagraphHTML('Searching...') - - cityssm.postJSON( - `${los.urlPrefix}/lots/doSearchLots`, - searchFormElement, - (rawResponseJSON) => { - const responseJSON = rawResponseJSON as { lots: Lot[] } - - if (responseJSON.lots.length === 0) { - searchResultsContainerElement.innerHTML = `
    -

    There are no records that meet the search criteria.

    -
    ` - - return - } - - // eslint-disable-next-line no-unsanitized/property - searchResultsContainerElement.innerHTML = ` - - - - - - - - -
    ${los.escapedAliases.Lot}${los.escapedAliases.Map}${los.escapedAliases.Lot} TypeStatus
    ` - - for (const lot of responseJSON.lots) { - const rowElement = document.createElement('tr') - rowElement.className = 'container--lot' - rowElement.dataset.lotId = lot.lotId.toString() - - rowElement.innerHTML = ` - - - ${cityssm.escapeHTML(lot.lotName ?? '')} - - ${cityssm.escapeHTML(lot.mapName ?? '')} - - ${cityssm.escapeHTML(lot.lotType ?? '')} - - ${cityssm.escapeHTML(lot.lotStatus ?? '')} - ` - - rowElement - .querySelector('.button--addLot') - ?.addEventListener('click', doAddLot) - - searchResultsContainerElement - .querySelector('tbody') - ?.append(rowElement) - } - } - ) - } - - cityssm.openHtmlModal('workOrder-addLot', { - onshow(modalElement) { - los.populateAliases(modalElement) - - searchFormElement = modalElement.querySelector('form') as HTMLFormElement - - searchResultsContainerElement = modalElement.querySelector( - '#resultsContainer--lotAdd' - ) as HTMLElement - ;( - modalElement.querySelector( - '#lotSearch--notWorkOrderId' - ) as HTMLInputElement - ).value = workOrderId - - const lotStatusElement = modalElement.querySelector( - '#lotSearch--lotStatusId' - ) as HTMLSelectElement - - for (const lotStatus of exports.lotStatuses as LotStatus[]) { - const optionElement = document.createElement('option') - optionElement.value = lotStatus.lotStatusId.toString() - optionElement.textContent = lotStatus.lotStatus - lotStatusElement.append(optionElement) - } - - doSearch() - }, - onshown(modalElement) { - bulmaJS.toggleHtmlClipped() - - const lotNameElement = modalElement.querySelector( - '#lotSearch--lotName' - ) as HTMLInputElement - - lotNameElement.addEventListener('change', doSearch) - lotNameElement.focus() - - modalElement - .querySelector('#lotSearch--lotStatusId') - ?.addEventListener('change', doSearch) - - searchFormElement.addEventListener('submit', doSearch) - }, - onremoved() { - bulmaJS.toggleHtmlClipped() - ;(document.querySelector('#button--addLot') as HTMLButtonElement).focus() - } - }) -}) diff --git a/public-typescript/adminDatabase.d.ts b/public/javascripts/adminDatabase.d.ts similarity index 100% rename from public-typescript/adminDatabase.d.ts rename to public/javascripts/adminDatabase.d.ts diff --git a/public-typescript/adminDatabase.js b/public/javascripts/adminDatabase.js similarity index 100% rename from public-typescript/adminDatabase.js rename to public/javascripts/adminDatabase.js diff --git a/public/javascripts/adminDatabase.min.js b/public/javascripts/adminDatabase.min.js deleted file mode 100644 index fe298c9e..00000000 --- a/public/javascripts/adminDatabase.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e,a;const t=exports.los;function s(){cityssm.postJSON(`${t.urlPrefix}/admin/doBackupDatabase`,{},e=>{var a;const t=e;t.success?bulmaJS.alert({title:"Database Backed Up Successfully",message:`Backed up to ${t.fileName}
    \n To request a copy of the backup, contact your application administrator.`,messageIsHtml:!0,contextualColorName:"success"}):bulmaJS.alert({title:"Error Backing Up Database",message:null!==(a=t.errorMessage)&&void 0!==a?a:"",contextualColorName:"danger"})})}function o(){cityssm.postJSON(`${t.urlPrefix}/admin/doCleanupDatabase`,{},e=>{var a;const t=e;t.success?bulmaJS.alert({title:"Database Cleaned Up Successfully",message:`${t.inactivatedRecordCount} records inactivated,\n ${t.purgedRecordCount} permanently deleted.`,contextualColorName:"success"}):bulmaJS.alert({title:"Error Cleaning Database",message:null!==(a=t.errorMessage)&&void 0!==a?a:"",contextualColorName:"danger"})})}null===(e=document.querySelector("#button--cleanupDatabase"))||void 0===e||e.addEventListener("click",()=>{bulmaJS.confirm({title:"Cleanup Database",message:"Are you sure you want to cleanup up the database?",okButton:{text:"Yes, Cleanup Database",callbackFunction:o}})}),null===(a=document.querySelector("#button--backupDatabase"))||void 0===a||a.addEventListener("click",()=>{bulmaJS.confirm({title:"Backup Database",message:"Are you sure you want to backup up the database?",okButton:{text:"Yes, Backup Database",callbackFunction:s}})})})(); \ No newline at end of file diff --git a/public-typescript/adminDatabase.ts b/public/javascripts/adminDatabase.ts similarity index 98% rename from public-typescript/adminDatabase.ts rename to public/javascripts/adminDatabase.ts index 84e28514..ddba582a 100644 --- a/public-typescript/adminDatabase.ts +++ b/public/javascripts/adminDatabase.ts @@ -3,7 +3,7 @@ import type { BulmaJS } from '@cityssm/bulma-js/types.js' import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' -import type { LOS } from '../types/globalTypes.js' +import type { LOS } from '../../types/globalTypes.js' declare const cityssm: cityssmGlobal declare const bulmaJS: BulmaJS diff --git a/public-typescript/adminFees.d.ts b/public/javascripts/adminFees.d.ts similarity index 100% rename from public-typescript/adminFees.d.ts rename to public/javascripts/adminFees.d.ts diff --git a/public-typescript/adminFees.js b/public/javascripts/adminFees.js similarity index 100% rename from public-typescript/adminFees.js rename to public/javascripts/adminFees.js diff --git a/public/javascripts/adminFees.min.js b/public/javascripts/adminFees.min.js deleted file mode 100644 index ac7f4f33..00000000 --- a/public/javascripts/adminFees.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e;const t=exports.los,n=document.querySelector("#container--feeCategories");let o=exports.feeCategories;function s(e){return o.find(t=>t.feeCategoryId===e)}function a(e,t){return e.fees.find(e=>e.feeId===t)}function r(){var e,s,a,r,m,v,p,g,C,S,b,F,q,E,x,T,A,I;if(0!==o.length){n.innerHTML="";for(const L of o){const o=document.createElement("section");o.className="panel container--feeCategory",o.dataset.feeCategoryId=L.feeCategoryId.toString(),o.innerHTML=`
    \n
    \n
    \n

    ${cityssm.escapeHTML(null!==(e=L.feeCategory)&&void 0!==e?e:"")}

    \n ${L.isGroupedFee?'Grouped Fee':""}\n
    \n
    \n
    \n ${0===L.fees.length?'
    \n \n
    ':""}\n
    \n \n
    \n
    \n \n
    \n
    \n ${t.getMoveUpDownButtonFieldHTML("button--moveFeeCategoryUp","button--moveFeeCategoryDown")}\n
    \n
    \n
    \n
    `,0===L.fees.length&&(o.insertAdjacentHTML("beforeend",`
    \n
    \n

    \n There are no fees in the\n "${cityssm.escapeHTML(null!==(s=L.feeCategory)&&void 0!==s?s:"")}"\n category.\n

    \n
    \n
    `),null===(a=o.querySelector(".button--deleteFeeCategory"))||void 0===a||a.addEventListener("click",i));for(const e of L.fees){const n=document.createElement("div");n.className="panel-block is-block container--fee",n.dataset.feeId=e.feeId.toString();const s=null!==(r=e.isRequired)&&void 0!==r&&r||void 0!==e.occupancyTypeId||void 0!==e.lotTypeId;n.innerHTML=`
    \n
    \n

    \n ${cityssm.escapeHTML(null!==(m=e.feeName)&&void 0!==m?m:"")}
    \n \n ${cityssm.escapeHTML(null!==(v=e.feeDescription)&&void 0!==v?v:"").replaceAll("\n","
    ")}\n
    \n

    \n ${s?`

    \n ${null!==(p=e.isRequired)&&void 0!==p&&p?'Required':""}\n ${-1===(null!==(g=e.occupancyTypeId)&&void 0!==g?g:-1)?"":` \n \n ${cityssm.escapeHTML(null!==(C=e.occupancyType)&&void 0!==C?C:"")}\n `}\n ${-1===(null!==(S=e.lotTypeId)&&void 0!==S?S:-1)?"":` \n \n ${cityssm.escapeHTML(null!==(b=e.lotType)&&void 0!==b?b:"")}\n `}\n

    `:""}\n
    \n
    \n
    \n
    \n ${e.feeFunction?`${cityssm.escapeHTML(e.feeFunction)}
    \n Fee Function`:`\n $${(null!==(F=e.feeAmount)&&void 0!==F?F:0).toFixed(2)}
    \n Fee\n
    `}\n
    \n
    \n ${e.taxPercentage?`${e.taxPercentage.toString()}%`:`$${(null!==(q=e.taxAmount)&&void 0!==q?q:0).toFixed(2)}`}
    \n Tax\n
    \n
    \n ${e.includeQuantity?`${cityssm.escapeHTML(null!==(E=e.quantityUnit)&&void 0!==E?E:"")}
    \n Quantity`:""}\n
    \n
    \n
    \n
    \n ${t.getMoveUpDownButtonFieldHTML("button--moveFeeUp","button--moveFeeDown")}\n
    \n
    `,null===(x=n.querySelector(".a--editFee"))||void 0===x||x.addEventListener("click",f),null===(T=n.querySelector(".a--editFeeAmount"))||void 0===T||T.addEventListener("click",u),n.querySelector(".button--moveFeeUp").addEventListener("click",y),n.querySelector(".button--moveFeeDown").addEventListener("click",y),o.append(n)}null===(A=o.querySelector(".button--editFeeCategory"))||void 0===A||A.addEventListener("click",l),null===(I=o.querySelector(".button--addFee"))||void 0===I||I.addEventListener("click",d),o.querySelector(".button--moveFeeCategoryUp").addEventListener("click",c),o.querySelector(".button--moveFeeCategoryDown").addEventListener("click",c),n.append(o)}}else n.innerHTML='
    \n

    There are no available fees.

    \n
    '}function l(e){var n;const a=s(Number.parseInt(null!==(n=e.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId)&&void 0!==n?n:"",10));let l;function i(e){e.preventDefault(),cityssm.postJSON(`${t.urlPrefix}/admin/doUpdateFeeCategory`,e.currentTarget,e=>{var t;const n=e;n.success?(o=n.feeCategories,l(),r()):bulmaJS.alert({title:"Error Updating Fee Category",message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}cityssm.openHtmlModal("adminFees-editFeeCategory",{onshow(e){e.querySelector("#feeCategoryEdit--feeCategoryId").value=a.feeCategoryId.toString(),e.querySelector("#feeCategoryEdit--feeCategory").value=a.feeCategory,a.isGroupedFee&&(e.querySelector("#feeCategoryEdit--isGroupedFee").checked=!0)},onshown(e,t){var n;bulmaJS.toggleHtmlClipped(),l=t,null===(n=e.querySelector("form"))||void 0===n||n.addEventListener("submit",i),e.querySelector("#feeCategoryEdit--feeCategory").focus()},onremoved:()=>{bulmaJS.toggleHtmlClipped()}})}function i(e){var n;const s=Number.parseInt(null!==(n=e.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId)&&void 0!==n?n:"",10);bulmaJS.confirm({title:"Delete Fee Category?",message:"Are you sure you want to delete this fee category?",contextualColorName:"warning",okButton:{text:"Yes, Delete the Fee Category",callbackFunction:function(){cityssm.postJSON(`${t.urlPrefix}/admin/doDeleteFeeCategory`,{feeCategoryId:s},e=>{var t;const n=e;n.success?(o=n.feeCategories,r()):bulmaJS.alert({title:"Error Updating Fee Category",message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}}})}function c(e){var n;const s=e.currentTarget,a=null!==(n=s.closest(".container--feeCategory").dataset.feeCategoryId)&&void 0!==n?n:"";cityssm.postJSON(`${t.urlPrefix}/admin/${"up"===s.dataset.direction?"doMoveFeeCategoryUp":"doMoveFeeCategoryDown"}`,{feeCategoryId:a,moveToEnd:e.shiftKey?"1":"0"},e=>{var t;const n=e;n.success?(o=n.feeCategories,r()):bulmaJS.alert({title:"Error Moving Fee Category",message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}function d(e){var n;const s=Number.parseInt(null!==(n=e.currentTarget.closest(".container--feeCategory").dataset.feeCategoryId)&&void 0!==n?n:"",10);let a;function l(e){e.preventDefault(),cityssm.postJSON(`${t.urlPrefix}/admin/doAddFee`,e.currentTarget,e=>{var t;const n=e;n.success?(o=n.feeCategories,a(),r()):bulmaJS.alert({title:"Error Adding Fee",message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}cityssm.openHtmlModal("adminFees-addFee",{onshow(e){const n=e.querySelector("#feeAdd--feeCategoryId");for(const e of o){const t=document.createElement("option");t.value=e.feeCategoryId.toString(),t.textContent=e.feeCategory,e.feeCategoryId===s&&(t.selected=!0),n.append(t)}const a=e.querySelector("#feeAdd--occupancyTypeId");for(const e of exports.occupancyTypes){const t=document.createElement("option");t.value=e.occupancyTypeId.toString(),t.textContent=e.occupancyType,a.append(t)}const r=e.querySelector("#feeAdd--lotTypeId");for(const e of exports.lotTypes){const t=document.createElement("option");t.value=e.lotTypeId.toString(),t.textContent=e.lotType,r.append(t)}e.querySelector("#feeAdd--taxPercentage").value=exports.taxPercentageDefault.toString(),t.populateAliases(e)},onshown(e,t){var n,o,s;bulmaJS.toggleHtmlClipped(),a=t,null===(n=e.querySelector("form"))||void 0===n||n.addEventListener("submit",l),e.querySelector("#feeAdd--feeName").focus(),e.querySelector("#feeAdd--feeFunction").addEventListener("change",()=>{var t,n;const o=e.querySelector("#feeAdd--feeAmount"),s=e.querySelector("#feeAdd--feeFunction");""===s.value?(null===(t=s.closest(".select"))||void 0===t||t.classList.remove("is-success"),o.classList.add("is-success"),o.disabled=!1):(null===(n=s.closest(".select"))||void 0===n||n.classList.add("is-success"),o.classList.remove("is-success"),o.disabled=!0)}),null===(o=e.querySelector("#feeAdd--taxPercentage"))||void 0===o||o.addEventListener("keyup",()=>{const t=e.querySelector("#feeAdd--taxAmount"),n=e.querySelector("#feeAdd--taxPercentage");""===n.value?(n.classList.remove("is-success"),t.classList.add("is-success"),t.disabled=!1):(n.classList.add("is-success"),t.classList.remove("is-success"),t.disabled=!0)}),null===(s=e.querySelector("#feeAdd--includeQuantity"))||void 0===s||s.addEventListener("change",()=>{e.querySelector("#feeAdd--quantityUnit").disabled=""===e.querySelector("#feeAdd--includeQuantity").value})},onremoved(){bulmaJS.toggleHtmlClipped()}})}function u(e){var n,l;e.preventDefault();const i=e.currentTarget.closest(".container--fee"),c=Number.parseInt(null!==(n=i.dataset.feeId)&&void 0!==n?n:"",10),d=s(Number.parseInt(null!==(l=i.closest(".container--feeCategory").dataset.feeCategoryId)&&void 0!==l?l:"")),u=a(d,c);let f;function y(e){e.preventDefault(),cityssm.postJSON(`${t.urlPrefix}/admin/doUpdateFeeAmount`,e.currentTarget,e=>{var t;const n=e;n.success?(o=n.feeCategories,f(),r()):bulmaJS.alert({title:"Error Updating Fee Amount",message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}cityssm.openHtmlModal("adminFees-editFeeAmount",{onshow(e){var t,n,o;e.querySelector("#feeAmountEdit--feeId").value=u.feeId.toString(),e.querySelector("#feeAmountEdit--feeCategory").textContent=d.feeCategory,e.querySelector("#feeAmountEdit--feeName").textContent=null!==(t=u.feeName)&&void 0!==t?t:"",e.querySelector("#feeAmountEdit--feeAmount").value=null!==(o=null===(n=u.feeAmount)||void 0===n?void 0:n.toFixed(2))&&void 0!==o?o:"0"},onshown(e,t){var n;e.querySelector("#feeAmountEdit--feeAmount").select(),f=t,null===(n=e.querySelector("form"))||void 0===n||n.addEventListener("submit",y)}})}function f(e){var n,l;e.preventDefault();const i=e.currentTarget.closest(".container--fee"),c=Number.parseInt(null!==(n=i.dataset.feeId)&&void 0!==n?n:"",10),d=Number.parseInt(null!==(l=i.closest(".container--feeCategory").dataset.feeCategoryId)&&void 0!==l?l:""),u=a(s(d),c);let f,y;function m(e){e.preventDefault(),cityssm.postJSON(`${t.urlPrefix}/admin/doUpdateFee`,e.currentTarget,e=>{var t;const n=e;n.success?(o=n.feeCategories,f(),r()):bulmaJS.alert({title:"Error Updating Fee",message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}function v(e){e.preventDefault(),bulmaJS.confirm({title:"Delete Fee?",message:"Are you sure you want to delete this fee?",contextualColorName:"warning",okButton:{text:"Yes, Delete the Fee",callbackFunction:function(){cityssm.postJSON(`${t.urlPrefix}/admin/doDeleteFee`,{feeId:c},e=>{var t;const n=e;n.success?(o=n.feeCategories,f(),r()):bulmaJS.alert({title:"Error Deleting Fee",message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}}})}function p(){var e,t;const n=y.querySelector("#feeEdit--feeAmount"),o=y.querySelector("#feeEdit--feeFunction");""===o.value?(null===(e=o.closest(".select"))||void 0===e||e.classList.remove("is-success"),n.classList.add("is-success"),n.disabled=!1):(null===(t=o.closest(".select"))||void 0===t||t.classList.add("is-success"),n.classList.remove("is-success"),n.disabled=!0)}function g(){const e=y.querySelector("#feeEdit--taxAmount"),t=y.querySelector("#feeEdit--taxPercentage");""===t.value?(t.classList.remove("is-success"),e.classList.add("is-success"),e.disabled=!1):(t.classList.add("is-success"),e.classList.remove("is-success"),e.disabled=!0)}function C(){const e=y.querySelector("#feeEdit--includeQuantity").value;y.querySelector("#feeEdit--quantityUnit").disabled=""===e}cityssm.openHtmlModal("adminFees-editFee",{onshow(e){var n,s,a,r,l,i,c;y=e,e.querySelector("#feeEdit--feeId").value=u.feeId.toString();const f=e.querySelector("#feeEdit--feeCategoryId");for(const e of o){const t=document.createElement("option");t.value=e.feeCategoryId.toString(),t.textContent=e.feeCategory,e.feeCategoryId===d&&(t.selected=!0),f.append(t)}e.querySelector("#feeEdit--feeName").value=null!==(n=u.feeName)&&void 0!==n?n:"",e.querySelector("#feeEdit--feeAccount").value=null!==(s=u.feeAccount)&&void 0!==s?s:"",e.querySelector("#feeEdit--feeDescription").value=null!==(a=u.feeDescription)&&void 0!==a?a:"";const m=e.querySelector("#feeEdit--occupancyTypeId");for(const e of exports.occupancyTypes){const t=document.createElement("option");t.value=e.occupancyTypeId.toString(),t.textContent=e.occupancyType,e.occupancyTypeId===u.occupancyTypeId&&(t.selected=!0),m.append(t)}const v=e.querySelector("#feeEdit--lotTypeId");for(const e of exports.lotTypes){const t=document.createElement("option");t.value=e.lotTypeId.toString(),t.textContent=e.lotType,e.lotTypeId===u.lotTypeId&&(t.selected=!0),v.append(t)}e.querySelector("#feeEdit--feeAmount").value=u.feeAmount?u.feeAmount.toFixed(2):"",null===(r=e.querySelector("#feeEdit--feeFunction"))||void 0===r||r.addEventListener("change",p),p(),e.querySelector("#feeEdit--taxAmount").value=u.taxAmount?u.taxAmount.toFixed(2):"";const S=e.querySelector("#feeEdit--taxPercentage");S.value=u.taxPercentage?u.taxPercentage.toString():"",S.addEventListener("keyup",g),g();const b=e.querySelector("#feeEdit--includeQuantity");null!==(l=u.includeQuantity)&&void 0!==l&&l&&(b.value="1"),b.addEventListener("change",C),e.querySelector("#feeEdit--quantityUnit").value=null!==(i=u.quantityUnit)&&void 0!==i?i:"",C(),null!==(c=u.isRequired)&&void 0!==c&&c&&(e.querySelector("#feeEdit--isRequired").value="1"),t.populateAliases(e)},onshown(e,t){var n,o;bulmaJS.toggleHtmlClipped(),f=t,null===(n=e.querySelector("form"))||void 0===n||n.addEventListener("submit",m),bulmaJS.init(e),null===(o=e.querySelector(".button--deleteFee"))||void 0===o||o.addEventListener("click",v)},onremoved(){bulmaJS.toggleHtmlClipped()}})}function y(e){var n;const s=e.currentTarget,a=null!==(n=s.closest(".container--fee").dataset.feeId)&&void 0!==n?n:"";cityssm.postJSON(`${t.urlPrefix}/admin/${"up"===s.dataset.direction?"doMoveFeeUp":"doMoveFeeDown"}`,{feeId:a,moveToEnd:e.shiftKey?"1":"0"},e=>{var t;const n=e;n.success?(o=n.feeCategories,r()):bulmaJS.alert({title:"Error Moving Fee",message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}delete exports.feeCategories,null===(e=document.querySelector("#button--addFeeCategory"))||void 0===e||e.addEventListener("click",()=>{let e;function n(n){n.preventDefault(),cityssm.postJSON(`${t.urlPrefix}/admin/doAddFeeCategory`,n.currentTarget,t=>{var n;const s=t;s.success?(o=s.feeCategories,e(),r()):bulmaJS.alert({title:"Error Creating Fee Category",message:null!==(n=s.errorMessage)&&void 0!==n?n:"",contextualColorName:"danger"})})}cityssm.openHtmlModal("adminFees-addFeeCategory",{onshown(t,o){var s;bulmaJS.toggleHtmlClipped(),t.querySelector("#feeCategoryAdd--feeCategory").focus(),e=o,null===(s=t.querySelector("form"))||void 0===s||s.addEventListener("submit",n)},onremoved(){bulmaJS.toggleHtmlClipped(),document.querySelector("#button--addFeeCategory").focus()}})}),r()})(); \ No newline at end of file diff --git a/public-typescript/adminFees.ts b/public/javascripts/adminFees.ts similarity index 99% rename from public-typescript/adminFees.ts rename to public/javascripts/adminFees.ts index 0ce7d320..00c2160b 100644 --- a/public-typescript/adminFees.ts +++ b/public/javascripts/adminFees.ts @@ -4,13 +4,13 @@ import type { BulmaJS } from '@cityssm/bulma-js/types.js' import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' -import type { LOS } from '../types/globalTypes.js' +import type { LOS } from '../../types/globalTypes.js' import type { Fee, FeeCategory, LotType, OccupancyType -} from '../types/recordTypes.js' +} from '../../types/recordTypes.js' declare const cityssm: cityssmGlobal declare const bulmaJS: BulmaJS diff --git a/public-typescript/adminLotTypes.d.ts b/public/javascripts/adminLotTypes.d.ts similarity index 100% rename from public-typescript/adminLotTypes.d.ts rename to public/javascripts/adminLotTypes.d.ts diff --git a/public-typescript/adminLotTypes.js b/public/javascripts/adminLotTypes.js similarity index 100% rename from public-typescript/adminLotTypes.js rename to public/javascripts/adminLotTypes.js diff --git a/public/javascripts/adminLotTypes.min.js b/public/javascripts/adminLotTypes.min.js deleted file mode 100644 index 10a845f6..00000000 --- a/public/javascripts/adminLotTypes.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e;const t=exports.los,l=document.querySelector("#container--lotTypes");let o=exports.lotTypes;delete exports.lotTypes;const n=new Set;function i(e){var t;const l=e.currentTarget,o=l.closest(".container--lotType"),i=Number.parseInt(null!==(t=o.dataset.lotTypeId)&&void 0!==t?t:"",10);n.has(i)?n.delete(i):n.add(i),l.innerHTML=n.has(i)?'':'';const s=o.querySelectorAll(".panel-block");for(const e of s)e.classList.toggle("is-hidden")}function s(e){var l;const n=e;n.success?(o=n.lotTypes,T()):bulmaJS.alert({title:`Error Updating ${t.escapedAliases.Lot} Type`,message:null!==(l=n.errorMessage)&&void 0!==l?l:"",contextualColorName:"danger"})}function d(e){var l;const o=Number.parseInt(null!==(l=e.currentTarget.closest(".container--lotType").dataset.lotTypeId)&&void 0!==l?l:"",10);bulmaJS.confirm({title:`Delete ${t.escapedAliases.Lot} Type`,message:`Are you sure you want to delete this ${t.escapedAliases.lot} type?`,contextualColorName:"warning",okButton:{text:`Yes, Delete ${t.escapedAliases.Lot} Type`,callbackFunction:function(){cityssm.postJSON(`${t.urlPrefix}/admin/doDeleteLotType`,{lotTypeId:o},s)}}})}function a(e){var l;const n=Number.parseInt(null!==(l=e.currentTarget.closest(".container--lotType").dataset.lotTypeId)&&void 0!==l?l:"",10),i=o.find(e=>n===e.lotTypeId);let d;function a(e){e.preventDefault(),cityssm.postJSON(`${t.urlPrefix}/admin/doUpdateLotType`,e.currentTarget,e=>{const t=e;s(t),t.success&&d()})}cityssm.openHtmlModal("adminLotTypes-editLotType",{onshow(e){t.populateAliases(e),e.querySelector("#lotTypeEdit--lotTypeId").value=n.toString(),e.querySelector("#lotTypeEdit--lotType").value=i.lotType},onshown(e,t){var l;d=t,e.querySelector("#lotTypeEdit--lotType").focus(),null===(l=e.querySelector("form"))||void 0===l||l.addEventListener("submit",a),bulmaJS.toggleHtmlClipped()},onremoved(){bulmaJS.toggleHtmlClipped()}})}function r(e){var l;const o=Number.parseInt(null!==(l=e.currentTarget.closest(".container--lotType").dataset.lotTypeId)&&void 0!==l?l:"",10);let i;function d(e){e.preventDefault(),cityssm.postJSON(`${t.urlPrefix}/admin/doAddLotTypeField`,e.currentTarget,e=>{const t=e;n.add(o),s(t),t.success&&(i(),u(o,t.lotTypeFieldId))})}cityssm.openHtmlModal("adminLotTypes-addLotTypeField",{onshow(e){t.populateAliases(e),o&&(e.querySelector("#lotTypeFieldAdd--lotTypeId").value=o.toString())},onshown(e,t){var l;i=t,e.querySelector("#lotTypeFieldAdd--lotTypeField").focus(),null===(l=e.querySelector("form"))||void 0===l||l.addEventListener("submit",d),bulmaJS.toggleHtmlClipped()},onremoved(){bulmaJS.toggleHtmlClipped()}})}function c(e){const l=e.currentTarget,o=l.closest(".container--lotType").dataset.lotTypeId;cityssm.postJSON(`${t.urlPrefix}/admin/${"up"===l.dataset.direction?"doMoveLotTypeUp":"doMoveLotTypeDown"}`,{lotTypeId:o,moveToEnd:e.shiftKey?"1":"0"},s)}function u(e,l){var n;const i=(null!==(n=o.find(t=>t.lotTypeId===e).lotTypeFields)&&void 0!==n?n:[]).find(e=>e.lotTypeFieldId===l);let d,a,r,c,u;function p(){a.min=d.value}function y(){""===c.value?(d.disabled=!1,a.disabled=!1,r.disabled=!1):(d.disabled=!0,a.disabled=!0,r.disabled=!0)}function v(e){e.preventDefault(),cityssm.postJSON(`${t.urlPrefix}/admin/doUpdateLotTypeField`,e.currentTarget,e=>{const t=e;s(t),t.success&&u()})}function T(){cityssm.postJSON(`${t.urlPrefix}/admin/doDeleteLotTypeField`,{lotTypeFieldId:l},e=>{const t=e;s(t),t.success&&u()})}function m(){bulmaJS.confirm({title:"Delete Field",message:"Are you sure you want to delete this field? Note that historical records that make use of this field will not be affected.",contextualColorName:"warning",okButton:{text:"Yes, Delete Field",callbackFunction:T}})}cityssm.openHtmlModal("adminLotTypes-editLotTypeField",{onshow(e){var l,o,n,s,u,p,v;t.populateAliases(e),e.querySelector("#lotTypeFieldEdit--lotTypeFieldId").value=i.lotTypeFieldId.toString(),e.querySelector("#lotTypeFieldEdit--lotTypeField").value=null!==(l=i.lotTypeField)&&void 0!==l?l:"",e.querySelector("#lotTypeFieldEdit--isRequired").value=i.isRequired?"1":"0",(d=e.querySelector("#lotTypeFieldEdit--minimumLength")).value=null!==(n=null===(o=i.minimumLength)||void 0===o?void 0:o.toString())&&void 0!==n?n:"",(a=e.querySelector("#lotTypeFieldEdit--maximumLength")).value=null!==(u=null===(s=i.maximumLength)||void 0===s?void 0:s.toString())&&void 0!==u?u:"",(r=e.querySelector("#lotTypeFieldEdit--pattern")).value=null!==(p=i.pattern)&&void 0!==p?p:"",(c=e.querySelector("#lotTypeFieldEdit--lotTypeFieldValues")).value=null!==(v=i.lotTypeFieldValues)&&void 0!==v?v:"",y()},onshown(e,t){var l,o;u=t,bulmaJS.init(e),bulmaJS.toggleHtmlClipped(),cityssm.enableNavBlocker(),null===(l=e.querySelector("form"))||void 0===l||l.addEventListener("submit",v),d.addEventListener("keyup",p),p(),c.addEventListener("keyup",y),null===(o=e.querySelector("#button--deleteLotTypeField"))||void 0===o||o.addEventListener("click",m)},onremoved(){bulmaJS.toggleHtmlClipped(),cityssm.disableNavBlocker()}})}function p(e){var t,l;e.preventDefault();const o=Number.parseInt(null!==(t=e.currentTarget.closest(".container--lotTypeField").dataset.lotTypeFieldId)&&void 0!==t?t:"",10);u(Number.parseInt(null!==(l=e.currentTarget.closest(".container--lotType").dataset.lotTypeId)&&void 0!==l?l:"",10),o)}function y(e){const l=e.currentTarget,o=l.closest(".container--lotTypeField").dataset.lotTypeFieldId;cityssm.postJSON(`${t.urlPrefix}/admin/${"up"===l.dataset.direction?"doMoveLotTypeFieldUp":"doMoveLotTypeFieldDown"}`,{lotTypeFieldId:o,moveToEnd:e.shiftKey?"1":"0"},s)}function v(e,l,o){var i,s;if(0===o.length)e.insertAdjacentHTML("beforeend",`
    \n

    There are no additional fields.

    \n
    `);else for(const d of o){const o=document.createElement("div");o.className="panel-block is-block container--lotTypeField",n.has(l)||o.classList.add("is-hidden"),o.dataset.lotTypeFieldId=d.lotTypeFieldId.toString(),o.innerHTML=`
    \n \n
    \n
    \n ${t.getMoveUpDownButtonFieldHTML("button--moveLotTypeFieldUp","button--moveLotTypeFieldDown")}\n
    \n
    \n
    `,null===(s=o.querySelector(".button--editLotTypeField"))||void 0===s||s.addEventListener("click",p),o.querySelector(".button--moveLotTypeFieldUp").addEventListener("click",y),o.querySelector(".button--moveLotTypeFieldDown").addEventListener("click",y),e.append(o)}}function T(){var e,s,u,p,y;if(l.innerHTML="",0!==o.length)for(const T of o){const o=document.createElement("div");o.className="panel container--lotType",o.dataset.lotTypeId=T.lotTypeId.toString(),o.innerHTML=`
    \n
    \n
    \n
    \n \n
    \n
    \n

    ${cityssm.escapeHTML(T.lotType)}

    \n
    \n
    \n
    \n
    \n \n
    \n
    \n \n
    \n
    \n \n
    \n
    \n ${t.getMoveUpDownButtonFieldHTML("button--moveLotTypeUp","button--moveLotTypeDown")}\n
    \n
    \n
    \n
    `,v(o,T.lotTypeId,null!==(e=T.lotTypeFields)&&void 0!==e?e:[]),null===(s=o.querySelector(".button--toggleLotTypeFields"))||void 0===s||s.addEventListener("click",i),null===(u=o.querySelector(".button--deleteLotType"))||void 0===u||u.addEventListener("click",d),null===(p=o.querySelector(".button--editLotType"))||void 0===p||p.addEventListener("click",a),null===(y=o.querySelector(".button--addLotTypeField"))||void 0===y||y.addEventListener("click",r),o.querySelector(".button--moveLotTypeUp").addEventListener("click",c),o.querySelector(".button--moveLotTypeDown").addEventListener("click",c),l.append(o)}else l.insertAdjacentHTML("afterbegin",`
    There are no active ${t.escapedAliases.lot} types.

    \n
    `)}null===(e=document.querySelector("#button--addLotType"))||void 0===e||e.addEventListener("click",()=>{let e;function l(l){l.preventDefault(),cityssm.postJSON(`${t.urlPrefix}/admin/doAddLotType`,l.currentTarget,l=>{var n;const i=l;i.success?(e(),o=i.lotTypes,T()):bulmaJS.alert({title:`Error Adding ${t.escapedAliases.Lot} Type`,message:null!==(n=i.errorMessage)&&void 0!==n?n:"",contextualColorName:"danger"})})}cityssm.openHtmlModal("adminLotTypes-addLotType",{onshow(e){t.populateAliases(e)},onshown(t,o){var n;e=o,t.querySelector("#lotTypeAdd--lotType").focus(),null===(n=t.querySelector("form"))||void 0===n||n.addEventListener("submit",l),bulmaJS.toggleHtmlClipped()},onremoved(){bulmaJS.toggleHtmlClipped()}})}),T()})(); \ No newline at end of file diff --git a/public-typescript/adminLotTypes.ts b/public/javascripts/adminLotTypes.ts similarity index 99% rename from public-typescript/adminLotTypes.ts rename to public/javascripts/adminLotTypes.ts index 34c4879a..fa10978d 100644 --- a/public-typescript/adminLotTypes.ts +++ b/public/javascripts/adminLotTypes.ts @@ -4,8 +4,8 @@ import type { BulmaJS } from '@cityssm/bulma-js/types.js' import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' -import type { LOS } from '../types/globalTypes.js' -import type { LotType, LotTypeField } from '../types/recordTypes.js' +import type { LOS } from '../../types/globalTypes.js' +import type { LotType, LotTypeField } from '../../types/recordTypes.js' declare const cityssm: cityssmGlobal declare const bulmaJS: BulmaJS diff --git a/public-typescript/adminOccupancyTypes.d.ts b/public/javascripts/adminOccupancyTypes.d.ts similarity index 100% rename from public-typescript/adminOccupancyTypes.d.ts rename to public/javascripts/adminOccupancyTypes.d.ts diff --git a/public-typescript/adminOccupancyTypes.js b/public/javascripts/adminOccupancyTypes.js similarity index 100% rename from public-typescript/adminOccupancyTypes.js rename to public/javascripts/adminOccupancyTypes.js diff --git a/public/javascripts/adminOccupancyTypes.min.js b/public/javascripts/adminOccupancyTypes.min.js deleted file mode 100644 index 2d1ebc78..00000000 --- a/public/javascripts/adminOccupancyTypes.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e;const c=exports.los,n=document.querySelector("#container--occupancyTypes"),t=document.querySelector("#container--occupancyTypePrints");let a=exports.occupancyTypes;delete exports.occupancyTypes;let i=exports.allOccupancyTypeFields;delete exports.allOccupancyTypeFields;const l=new Set;function s(e){var c;const n=e.currentTarget,t=n.closest(".container--occupancyType"),a=Number.parseInt(null!==(c=t.dataset.occupancyTypeId)&&void 0!==c?c:"",10);l.has(a)?l.delete(a):l.add(a),n.innerHTML=l.has(a)?'':'';const i=t.querySelectorAll(".panel-block");for(const e of i)e.classList.toggle("is-hidden")}function o(e){var n;const t=e;t.success?(a=t.occupancyTypes,i=t.allOccupancyTypeFields,O()):bulmaJS.alert({title:`Error Updating ${c.escapedAliases.Occupancy} Type`,message:null!==(n=t.errorMessage)&&void 0!==n?n:"",contextualColorName:"danger"})}function d(e){var n;const t=Number.parseInt(null!==(n=e.currentTarget.closest(".container--occupancyType").dataset.occupancyTypeId)&&void 0!==n?n:"",10);bulmaJS.confirm({title:`Delete ${c.escapedAliases.Occupancy} Type`,message:`Are you sure you want to delete this ${c.escapedAliases.occupancy} type?`,contextualColorName:"warning",okButton:{text:`Yes, Delete ${c.escapedAliases.Occupancy} Type`,callbackFunction:function(){cityssm.postJSON(`${c.urlPrefix}/admin/doDeleteOccupancyType`,{occupancyTypeId:t},o)}}})}function p(e){var n;const t=Number.parseInt(null!==(n=e.currentTarget.closest(".container--occupancyType").dataset.occupancyTypeId)&&void 0!==n?n:"",10),i=a.find(e=>t===e.occupancyTypeId);let l;function s(e){e.preventDefault(),cityssm.postJSON(`${c.urlPrefix}/admin/doUpdateOccupancyType`,e.currentTarget,e=>{const c=e;o(c),c.success&&l()})}cityssm.openHtmlModal("adminOccupancyTypes-editOccupancyType",{onshow(e){c.populateAliases(e),e.querySelector("#occupancyTypeEdit--occupancyTypeId").value=t.toString(),e.querySelector("#occupancyTypeEdit--occupancyType").value=i.occupancyType},onshown(e,c){var n;l=c,e.querySelector("#occupancyTypeEdit--occupancyType").focus(),null===(n=e.querySelector("form"))||void 0===n||n.addEventListener("submit",s),bulmaJS.toggleHtmlClipped()},onremoved(){bulmaJS.toggleHtmlClipped()}})}function u(e){var n;const t=Number.parseInt(null!==(n=e.currentTarget.closest(".container--occupancyType").dataset.occupancyTypeId)&&void 0!==n?n:"",10);let a;function i(e){e.preventDefault(),cityssm.postJSON(`${c.urlPrefix}/admin/doAddOccupancyTypeField`,e.currentTarget,e=>{var c;const n=e;l.add(t),o(n),n.success&&(a(),y(t,null!==(c=n.occupancyTypeFieldId)&&void 0!==c?c:0))})}cityssm.openHtmlModal("adminOccupancyTypes-addOccupancyTypeField",{onshow(e){c.populateAliases(e),t&&(e.querySelector("#occupancyTypeFieldAdd--occupancyTypeId").value=t.toString())},onshown(e,c){var n;a=c,e.querySelector("#occupancyTypeFieldAdd--occupancyTypeField").focus(),null===(n=e.querySelector("form"))||void 0===n||n.addEventListener("submit",i),bulmaJS.toggleHtmlClipped()},onremoved(){bulmaJS.toggleHtmlClipped()}})}function r(e){const n=e.currentTarget,t=e.currentTarget.closest(".container--occupancyType").dataset.occupancyTypeId;cityssm.postJSON(`${c.urlPrefix}/admin/${"up"===n.dataset.direction?"doMoveOccupancyTypeUp":"doMoveOccupancyTypeDown"}`,{occupancyTypeId:t,moveToEnd:e.shiftKey?"1":"0"},o)}function y(e,n){var t;let l;e&&(l=a.find(c=>c.occupancyTypeId===e));const s=(l?null!==(t=l.occupancyTypeFields)&&void 0!==t?t:[]:i).find(e=>e.occupancyTypeFieldId===n);let d,p,u,r,y;function v(){p.min=d.value}function T(){""===r.value?(d.disabled=!1,p.disabled=!1,u.disabled=!1):(d.disabled=!0,p.disabled=!0,u.disabled=!0)}function m(e){e.preventDefault(),cityssm.postJSON(`${c.urlPrefix}/admin/doUpdateOccupancyTypeField`,e.currentTarget,e=>{const c=e;o(c),c.success&&y()})}function f(){cityssm.postJSON(`${c.urlPrefix}/admin/doDeleteOccupancyTypeField`,{occupancyTypeFieldId:n},e=>{const c=e;o(c),c.success&&y()})}function b(){bulmaJS.confirm({title:"Delete Field",message:"Are you sure you want to delete this field? Note that historical records that make use of this field will not be affected.",contextualColorName:"warning",okButton:{text:"Yes, Delete Field",callbackFunction:f}})}cityssm.openHtmlModal("adminOccupancyTypes-editOccupancyTypeField",{onshow:e=>{var n,t,a,i,l,o,y,v;c.populateAliases(e),e.querySelector("#occupancyTypeFieldEdit--occupancyTypeFieldId").value=s.occupancyTypeFieldId.toString(),e.querySelector("#occupancyTypeFieldEdit--occupancyTypeField").value=null!==(n=s.occupancyTypeField)&&void 0!==n?n:"",e.querySelector("#occupancyTypeFieldEdit--isRequired").value=null!==(t=s.isRequired)&&void 0!==t&&t?"1":"0",(d=e.querySelector("#occupancyTypeFieldEdit--minimumLength")).value=null!==(i=null===(a=s.minimumLength)||void 0===a?void 0:a.toString())&&void 0!==i?i:"",(p=e.querySelector("#occupancyTypeFieldEdit--maximumLength")).value=null!==(o=null===(l=s.maximumLength)||void 0===l?void 0:l.toString())&&void 0!==o?o:"",(u=e.querySelector("#occupancyTypeFieldEdit--pattern")).value=null!==(y=s.pattern)&&void 0!==y?y:"",(r=e.querySelector("#occupancyTypeFieldEdit--occupancyTypeFieldValues")).value=null!==(v=s.occupancyTypeFieldValues)&&void 0!==v?v:"",T()},onshown:(e,c)=>{var n,t;y=c,bulmaJS.init(e),bulmaJS.toggleHtmlClipped(),cityssm.enableNavBlocker(),null===(n=e.querySelector("form"))||void 0===n||n.addEventListener("submit",m),d.addEventListener("keyup",v),v(),r.addEventListener("keyup",T),null===(t=e.querySelector("#button--deleteOccupancyTypeField"))||void 0===t||t.addEventListener("click",b)},onremoved:()=>{bulmaJS.toggleHtmlClipped(),cityssm.disableNavBlocker()}})}function v(e){var c,n;e.preventDefault();const t=Number.parseInt(null!==(c=e.currentTarget.closest(".container--occupancyTypeField").dataset.occupancyTypeFieldId)&&void 0!==c?c:"",10);y(Number.parseInt(null!==(n=e.currentTarget.closest(".container--occupancyType").dataset.occupancyTypeId)&&void 0!==n?n:"",10),t)}function T(e){const n=e.currentTarget,t=e.currentTarget.closest(".container--occupancyTypeField").dataset.occupancyTypeFieldId;cityssm.postJSON(`${c.urlPrefix}/admin/${"up"===n.dataset.direction?"doMoveOccupancyTypeFieldUp":"doMoveOccupancyTypeFieldDown"}`,{occupancyTypeFieldId:t,moveToEnd:e.shiftKey?"1":"0"},o)}function m(e,n,t){var a,i;if(0===t.length)e.insertAdjacentHTML("beforeend",`
    \n

    There are no additional fields.

    \n
    `);else for(const s of t){const t=document.createElement("div");t.className="panel-block is-block container--occupancyTypeField",n&&!l.has(n)&&t.classList.add("is-hidden"),t.dataset.occupancyTypeFieldId=s.occupancyTypeFieldId.toString(),t.innerHTML=`
    \n \n
    \n
    \n ${c.getMoveUpDownButtonFieldHTML("button--moveOccupancyTypeFieldUp","button--moveOccupancyTypeFieldDown")}\n
    \n
    \n
    `,null===(i=t.querySelector(".button--editOccupancyTypeField"))||void 0===i||i.addEventListener("click",v),t.querySelector(".button--moveOccupancyTypeFieldUp").addEventListener("click",T),t.querySelector(".button--moveOccupancyTypeFieldDown").addEventListener("click",T),e.append(t)}}function f(e){var n;const t=null!==(n=e.currentTarget.closest(".container--occupancyTypePrintList").dataset.occupancyTypeId)&&void 0!==n?n:"";let a;function i(e){e.preventDefault(),cityssm.postJSON(`${c.urlPrefix}/admin/doAddOccupancyTypePrint`,e.currentTarget,e=>{const c=e;c.success&&a(),o(c)})}cityssm.openHtmlModal("adminOccupancyTypes-addOccupancyTypePrint",{onshow(e){c.populateAliases(e),e.querySelector("#occupancyTypePrintAdd--occupancyTypeId").value=t;const n=e.querySelector("#occupancyTypePrintAdd--printEJS");for(const[e,c]of Object.entries(exports.occupancyTypePrintTitles)){const t=document.createElement("option");t.value=e,t.textContent=c,n.append(t)}},onshown(e,c){var n;a=c,null===(n=e.querySelector("form"))||void 0===n||n.addEventListener("submit",i)}})}function b(e){const n=e.currentTarget,t=n.closest(".container--occupancyTypePrint").dataset.printEJS,a=n.closest(".container--occupancyTypePrintList").dataset.occupancyTypeId;cityssm.postJSON(`${c.urlPrefix}/admin/${"up"===n.dataset.direction?"doMoveOccupancyTypePrintUp":"doMoveOccupancyTypePrintDown"}`,{occupancyTypeId:a,printEJS:t,moveToEnd:e.shiftKey?"1":"0"},o)}function g(e){e.preventDefault();const n=e.currentTarget.closest(".container--occupancyTypePrint").dataset.printEJS,t=e.currentTarget.closest(".container--occupancyTypePrintList").dataset.occupancyTypeId;bulmaJS.confirm({title:"Delete Print",message:"Are you sure you want to remove this print option?",contextualColorName:"warning",okButton:{text:"Yes, Remove Print",callbackFunction:function(){cityssm.postJSON(`${c.urlPrefix}/admin/doDeleteOccupancyTypePrint`,{occupancyTypeId:t,printEJS:n},o)}}})}function S(e,n,t){var a;if(0===t.length)e.insertAdjacentHTML("beforeend",'
    \n
    \n

    There are no prints associated with this record.

    \n
    \n
    ');else for(const n of t){const t=document.createElement("div");t.className="panel-block is-block container--occupancyTypePrint",t.dataset.printEJS=n;const i="*"===n?"(All Available Prints)":exports.occupancyTypePrintTitles[n];let l="fa-star";n.startsWith("pdf/")?l="fa-file-pdf":n.startsWith("screen/")&&(l="fa-file"),t.innerHTML=`
    \n
    \n
    \n \n
    \n
    \n ${cityssm.escapeHTML(i||n)}\n
    \n
    \n
    \n
    \n ${c.getMoveUpDownButtonFieldHTML("button--moveOccupancyTypePrintUp","button--moveOccupancyTypePrintDown")}\n
    \n
    \n \n
    \n
    \n
    `,t.querySelector(".button--moveOccupancyTypePrintUp").addEventListener("click",b),t.querySelector(".button--moveOccupancyTypePrintDown").addEventListener("click",b),null===(a=t.querySelector(".button--deleteOccupancyTypePrint"))||void 0===a||a.addEventListener("click",g),e.append(t)}}function O(){var e,o,y,v,T,b,g,O;if(n.innerHTML=`
    \n
    \n
    \n
    \n
    \n

    (All ${c.escapedAliases.Occupancy} Types)

    \n
    \n
    \n
    \n
    \n \n
    \n
    \n
    \n
    \n
    `,t.innerHTML="",m(n.querySelector("#container--allOccupancyTypeFields"),void 0,i),null===(e=n.querySelector(".button--addOccupancyTypeField"))||void 0===e||e.addEventListener("click",u),0===a.length)return n.insertAdjacentHTML("afterbegin",`
    There are no active ${c.escapedAliases.occupancy} types.

    \n
    `),void t.insertAdjacentHTML("afterbegin",`
    There are no active ${c.escapedAliases.occupancy} types.

    \n
    `);for(const e of a){const a=document.createElement("div");a.className="panel container--occupancyType",a.dataset.occupancyTypeId=e.occupancyTypeId.toString(),a.innerHTML=`
    \n
    \n
    \n
    \n \n
    \n
    \n

    ${cityssm.escapeHTML(e.occupancyType)}

    \n
    \n
    \n
    \n
    \n \n
    \n
    \n \n
    \n
    \n \n
    \n
    \n ${c.getMoveUpDownButtonFieldHTML("button--moveOccupancyTypeUp","button--moveOccupancyTypeDown")}\n
    \n
    \n
    \n
    `,m(a,e.occupancyTypeId,null!==(o=e.occupancyTypeFields)&&void 0!==o?o:[]),null===(y=a.querySelector(".button--toggleOccupancyTypeFields"))||void 0===y||y.addEventListener("click",s),null===(v=a.querySelector(".button--deleteOccupancyType"))||void 0===v||v.addEventListener("click",d),null===(T=a.querySelector(".button--editOccupancyType"))||void 0===T||T.addEventListener("click",p),null===(b=a.querySelector(".button--addOccupancyTypeField"))||void 0===b||b.addEventListener("click",u),a.querySelector(".button--moveOccupancyTypeUp").addEventListener("click",r),a.querySelector(".button--moveOccupancyTypeDown").addEventListener("click",r),n.append(a);const i=document.createElement("div");i.className="panel container--occupancyTypePrintList",i.dataset.occupancyTypeId=e.occupancyTypeId.toString(),i.innerHTML=`
    \n
    \n
    \n
    \n

    ${cityssm.escapeHTML(e.occupancyType)}

    \n
    \n
    \n
    \n
    \n \n
    \n
    \n
    \n
    `,S(i,e.occupancyTypeId,null!==(g=e.occupancyTypePrints)&&void 0!==g?g:[]),null===(O=i.querySelector(".button--addOccupancyTypePrint"))||void 0===O||O.addEventListener("click",f),t.append(i)}}null===(e=document.querySelector("#button--addOccupancyType"))||void 0===e||e.addEventListener("click",()=>{let e;function n(n){n.preventDefault(),cityssm.postJSON(`${c.urlPrefix}/admin/doAddOccupancyType`,n.currentTarget,n=>{var t;const i=n;i.success?(e(),a=i.occupancyTypes,O()):bulmaJS.alert({title:`Error Adding ${c.escapedAliases.Occupancy} Type`,message:null!==(t=i.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}cityssm.openHtmlModal("adminOccupancyTypes-addOccupancyType",{onshow(e){c.populateAliases(e)},onshown(c,t){var a;e=t,c.querySelector("#occupancyTypeAdd--occupancyType").focus(),null===(a=c.querySelector("form"))||void 0===a||a.addEventListener("submit",n),bulmaJS.toggleHtmlClipped()},onremoved(){bulmaJS.toggleHtmlClipped()}})}),O()})(); \ No newline at end of file diff --git a/public-typescript/adminOccupancyTypes.ts b/public/javascripts/adminOccupancyTypes.ts similarity index 99% rename from public-typescript/adminOccupancyTypes.ts rename to public/javascripts/adminOccupancyTypes.ts index 88773a78..2866fedd 100644 --- a/public-typescript/adminOccupancyTypes.ts +++ b/public/javascripts/adminOccupancyTypes.ts @@ -4,8 +4,8 @@ import type { BulmaJS } from '@cityssm/bulma-js/types.js' import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' -import type { LOS } from '../types/globalTypes.js' -import type { OccupancyType, OccupancyTypeField } from '../types/recordTypes.js' +import type { LOS } from '../../types/globalTypes.js' +import type { OccupancyType, OccupancyTypeField } from '../../types/recordTypes.js' declare const cityssm: cityssmGlobal declare const bulmaJS: BulmaJS diff --git a/public-typescript/adminTables/adminTables.d.ts b/public/javascripts/adminTables.d.ts similarity index 100% rename from public-typescript/adminTables/adminTables.d.ts rename to public/javascripts/adminTables.d.ts diff --git a/public/javascripts/adminTables.js b/public/javascripts/adminTables.js new file mode 100644 index 00000000..05f10d93 --- /dev/null +++ b/public/javascripts/adminTables.js @@ -0,0 +1,714 @@ +"use strict"; +// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair +/* eslint-disable unicorn/prefer-module */ +Object.defineProperty(exports, "__esModule", { value: true }); +(() => { + const los = exports.los; + function refreshFontAwesomeIcon(changeEvent) { + const inputElement = changeEvent.currentTarget; + const fontAwesomeIconClass = inputElement.value; + (inputElement.closest('.field')?.querySelectorAll('.button.is-static' + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + ))[1].innerHTML = + ``; + } + /** + * Work Order Types + */ + ; + (() => { + let workOrderTypes = exports.workOrderTypes; + delete exports.workOrderTypes; + function updateWorkOrderType(submitEvent) { + submitEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateWorkOrderType`, submitEvent.currentTarget, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderTypes = responseJSON.workOrderTypes; + bulmaJS.alert({ + message: 'Work Order Type Updated Successfully', + contextualColorName: 'success' + }); + } + else { + bulmaJS.alert({ + title: 'Error Updating Work Order Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + function deleteWorkOrderType(clickEvent) { + const tableRowElement = clickEvent.currentTarget.closest('tr'); + const workOrderTypeId = tableRowElement.dataset.workOrderTypeId; + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteWorkOrderType`, { + workOrderTypeId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderTypes = responseJSON.workOrderTypes; + if (workOrderTypes.length === 0) { + renderWorkOrderTypes(); + } + else { + tableRowElement.remove(); + } + bulmaJS.alert({ + message: 'Work Order Type Deleted Successfully', + contextualColorName: 'success' + }); + } + else { + bulmaJS.alert({ + title: 'Error Deleting Work Order Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + bulmaJS.confirm({ + title: 'Delete Work Order Type', + message: `Are you sure you want to delete this work order type?
    + Note that no work orders will be removed.`, + messageIsHtml: true, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Work Order Type', + callbackFunction: doDelete + } + }); + } + function moveWorkOrderType(clickEvent) { + const buttonElement = clickEvent.currentTarget; + const tableRowElement = buttonElement.closest('tr'); + const workOrderTypeId = tableRowElement.dataset.workOrderTypeId; + cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' + ? 'doMoveWorkOrderTypeUp' + : 'doMoveWorkOrderTypeDown'}`, { + workOrderTypeId, + moveToEnd: clickEvent.shiftKey ? '1' : '0' + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderTypes = responseJSON.workOrderTypes; + renderWorkOrderTypes(); + } + else { + bulmaJS.alert({ + title: 'Error Moving Work Order Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + function renderWorkOrderTypes() { + const containerElement = document.querySelector('#container--workOrderTypes'); + if (workOrderTypes.length === 0) { + containerElement.innerHTML = ` +

    There are no active work order types.

    + `; + return; + } + containerElement.innerHTML = ''; + for (const workOrderType of workOrderTypes) { + const tableRowElement = document.createElement('tr'); + tableRowElement.dataset.workOrderTypeId = + workOrderType.workOrderTypeId.toString(); + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + ${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderTypeUp', 'button--moveWorkOrderTypeDown', false)} +
    +
    + +
    +
    + `; + tableRowElement + .querySelector('form') + ?.addEventListener('submit', updateWorkOrderType); + tableRowElement.querySelector('.button--moveWorkOrderTypeUp').addEventListener('click', moveWorkOrderType); + tableRowElement.querySelector('.button--moveWorkOrderTypeDown').addEventListener('click', moveWorkOrderType); + tableRowElement + .querySelector('.button--deleteWorkOrderType') + ?.addEventListener('click', deleteWorkOrderType); + containerElement.append(tableRowElement); + } + } + ; + document.querySelector('#form--addWorkOrderType').addEventListener('submit', (submitEvent) => { + submitEvent.preventDefault(); + const formElement = submitEvent.currentTarget; + cityssm.postJSON(`${los.urlPrefix}/admin/doAddWorkOrderType`, formElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderTypes = responseJSON.workOrderTypes; + renderWorkOrderTypes(); + formElement.reset(); + formElement.querySelector('input')?.focus(); + } + else { + bulmaJS.alert({ + title: 'Error Adding Work Order Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + }); + renderWorkOrderTypes(); + })(); + (() => { + let workOrderMilestoneTypes = exports.workOrderMilestoneTypes; + delete exports.workOrderMilestoneTypes; + function updateWorkOrderMilestoneType(submitEvent) { + submitEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateWorkOrderMilestoneType`, submitEvent.currentTarget, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes; + bulmaJS.alert({ + message: 'Work Order Milestone Type Updated Successfully', + contextualColorName: 'success' + }); + } + else { + bulmaJS.alert({ + title: 'Error Updating Work Order Milestone Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + function deleteWorkOrderMilestoneType(clickEvent) { + const tableRowElement = clickEvent.currentTarget.closest('tr'); + const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId; + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteWorkOrderMilestoneType`, { + workOrderMilestoneTypeId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes; + if (workOrderMilestoneTypes.length === 0) { + renderWorkOrderMilestoneTypes(); + } + else { + tableRowElement.remove(); + } + bulmaJS.alert({ + message: 'Work Order Milestone Type Deleted Successfully', + contextualColorName: 'success' + }); + } + else { + bulmaJS.alert({ + title: 'Error Deleting Work Order Milestone Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + bulmaJS.confirm({ + title: 'Delete Work Order Milestone Type', + message: `Are you sure you want to delete this work order milestone type?
    + Note that no work orders will be removed.`, + messageIsHtml: true, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Work Order Milestone Type', + callbackFunction: doDelete + } + }); + } + function moveWorkOrderMilestoneType(clickEvent) { + const buttonElement = clickEvent.currentTarget; + const tableRowElement = buttonElement.closest('tr'); + const workOrderMilestoneTypeId = tableRowElement.dataset.workOrderMilestoneTypeId; + cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' + ? 'doMoveWorkOrderMilestoneTypeUp' + : 'doMoveWorkOrderMilestoneTypeDown'}`, { + workOrderMilestoneTypeId, + moveToEnd: clickEvent.shiftKey ? '1' : '0' + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes; + renderWorkOrderMilestoneTypes(); + } + else { + bulmaJS.alert({ + title: 'Error Moving Work Order Milestone Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + function renderWorkOrderMilestoneTypes() { + const containerElement = document.querySelector('#container--workOrderMilestoneTypes'); + if (workOrderMilestoneTypes.length === 0) { + containerElement.innerHTML = ` +

    There are no active work order milestone types.

    + `; + return; + } + containerElement.innerHTML = ''; + for (const workOrderMilestoneType of workOrderMilestoneTypes) { + const tableRowElement = document.createElement('tr'); + tableRowElement.dataset.workOrderMilestoneTypeId = + workOrderMilestoneType.workOrderMilestoneTypeId.toString(); + // eslint-disable-next-line no-unsanitized/property, no-secrets/no-secrets + tableRowElement.innerHTML = ` +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + ${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderMilestoneTypeUp', 'button--moveWorkOrderMilestoneTypeDown', false)} +
    +
    + +
    +
    + `; + tableRowElement + .querySelector('form') + ?.addEventListener('submit', updateWorkOrderMilestoneType); + tableRowElement.querySelector('.button--moveWorkOrderMilestoneTypeUp').addEventListener('click', moveWorkOrderMilestoneType); + tableRowElement.querySelector('.button--moveWorkOrderMilestoneTypeDown').addEventListener('click', moveWorkOrderMilestoneType); + tableRowElement + .querySelector('.button--deleteWorkOrderMilestoneType') + ?.addEventListener('click', deleteWorkOrderMilestoneType); + containerElement.append(tableRowElement); + } + } + ; + document.querySelector('#form--addWorkOrderMilestoneType').addEventListener('submit', (submitEvent) => { + submitEvent.preventDefault(); + const formElement = submitEvent.currentTarget; + cityssm.postJSON(`${los.urlPrefix}/admin/doAddWorkOrderMilestoneType`, formElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes; + renderWorkOrderMilestoneTypes(); + formElement.reset(); + formElement.querySelector('input')?.focus(); + } + else { + bulmaJS.alert({ + title: 'Error Adding Work Order Milestone Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + }); + renderWorkOrderMilestoneTypes(); + })(); + (() => { + let lotStatuses = exports.lotStatuses; + delete exports.lotStatuses; + function updateLotStatus(submitEvent) { + submitEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateLotStatus`, submitEvent.currentTarget, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotStatuses = responseJSON.lotStatuses; + bulmaJS.alert({ + message: `${los.escapedAliases.Lot} Status Updated Successfully`, + contextualColorName: 'success' + }); + } + else { + bulmaJS.alert({ + title: `Error Updating ${los.escapedAliases.Lot} Status`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + function deleteLotStatus(clickEvent) { + const tableRowElement = clickEvent.currentTarget.closest('tr'); + const lotStatusId = tableRowElement.dataset.lotStatusId; + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteLotStatus`, { + lotStatusId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotStatuses = responseJSON.lotStatuses; + if (lotStatuses.length === 0) { + renderLotStatuses(); + } + else { + tableRowElement.remove(); + } + bulmaJS.alert({ + message: `${los.escapedAliases.Lot} Status Deleted Successfully`, + contextualColorName: 'success' + }); + } + else { + bulmaJS.alert({ + title: `Error Deleting ${los.escapedAliases.Lot} Status`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + bulmaJS.confirm({ + title: `Delete ${los.escapedAliases.Lot} Status`, + message: `Are you sure you want to delete this status?
    + Note that no ${los.escapedAliases.lot} will be removed.`, + messageIsHtml: true, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Status', + callbackFunction: doDelete + } + }); + } + function moveLotStatus(clickEvent) { + const buttonElement = clickEvent.currentTarget; + const tableRowElement = buttonElement.closest('tr'); + const lotStatusId = tableRowElement.dataset.lotStatusId; + cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' + ? 'doMoveLotStatusUp' + : 'doMoveLotStatusDown'}`, { + lotStatusId, + moveToEnd: clickEvent.shiftKey ? '1' : '0' + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotStatuses = responseJSON.lotStatuses; + renderLotStatuses(); + } + else { + bulmaJS.alert({ + title: `Error Moving ${los.escapedAliases.Lot} Status`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + function renderLotStatuses() { + const containerElement = document.querySelector('#container--lotStatuses'); + if (lotStatuses.length === 0) { + // eslint-disable-next-line no-unsanitized/property + containerElement.innerHTML = ` +

    There are no active ${los.escapedAliases.lot} statuses.

    + `; + return; + } + containerElement.innerHTML = ''; + for (const lotStatus of lotStatuses) { + const tableRowElement = document.createElement('tr'); + tableRowElement.dataset.lotStatusId = lotStatus.lotStatusId.toString(); + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + ${los.getMoveUpDownButtonFieldHTML('button--moveLotStatusUp', 'button--moveLotStatusDown', false)} +
    +
    + +
    +
    + `; + tableRowElement + .querySelector('form') + ?.addEventListener('submit', updateLotStatus); + tableRowElement.querySelector('.button--moveLotStatusUp').addEventListener('click', moveLotStatus); + tableRowElement.querySelector('.button--moveLotStatusDown').addEventListener('click', moveLotStatus); + tableRowElement + .querySelector('.button--deleteLotStatus') + ?.addEventListener('click', deleteLotStatus); + containerElement.append(tableRowElement); + } + } + ; + document.querySelector('#form--addLotStatus').addEventListener('submit', (submitEvent) => { + submitEvent.preventDefault(); + const formElement = submitEvent.currentTarget; + cityssm.postJSON(`${los.urlPrefix}/admin/doAddLotStatus`, formElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotStatuses = responseJSON.lotStatuses; + renderLotStatuses(); + formElement.reset(); + formElement.querySelector('input')?.focus(); + } + else { + bulmaJS.alert({ + title: `Error Adding ${los.escapedAliases.Lot} Status`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + }); + renderLotStatuses(); + })(); + (() => { + let lotOccupantTypes = exports.lotOccupantTypes; + delete exports.lotOccupantTypes; + function updateLotOccupantType(submitEvent) { + submitEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/admin/doUpdateLotOccupantType`, submitEvent.currentTarget, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes; + bulmaJS.alert({ + message: `${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type Updated Successfully`, + contextualColorName: 'success' + }); + } + else { + bulmaJS.alert({ + title: `Error Updating ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + function deleteLotOccupantType(clickEvent) { + const tableRowElement = clickEvent.currentTarget.closest('tr'); + const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId; + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/admin/doDeleteLotOccupantType`, { + lotOccupantTypeId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes; + if (lotOccupantTypes.length === 0) { + renderLotOccupantTypes(); + } + else { + tableRowElement.remove(); + } + bulmaJS.alert({ + message: `${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type Deleted Successfully`, + contextualColorName: 'success' + }); + } + else { + bulmaJS.alert({ + title: `Error Deleting ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + bulmaJS.confirm({ + title: `Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, + message: `Are you sure you want to delete this ${los.escapedAliases.lot} ${los.escapedAliases.occupant} type?
    + Note that no ${los.escapedAliases.lot} ${los.escapedAliases.occupants} will be removed.`, + messageIsHtml: true, + contextualColorName: 'warning', + okButton: { + text: `Yes, Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, + callbackFunction: doDelete + } + }); + } + function moveLotOccupantType(clickEvent) { + const buttonElement = clickEvent.currentTarget; + const tableRowElement = buttonElement.closest('tr'); + const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId; + cityssm.postJSON(`${los.urlPrefix}/admin/${buttonElement.dataset.direction === 'up' + ? 'doMoveLotOccupantTypeUp' + : 'doMoveLotOccupantTypeDown'}`, { + lotOccupantTypeId, + moveToEnd: clickEvent.shiftKey ? '1' : '0' + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes; + renderLotOccupantTypes(); + } + else { + bulmaJS.alert({ + title: `Error Moving ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + function renderLotOccupantTypes() { + const containerElement = document.querySelector('#container--lotOccupantTypes'); + if (lotOccupantTypes.length === 0) { + // eslint-disable-next-line no-unsanitized/property + containerElement.innerHTML = ` +
    +

    There are no active ${los.escapedAliases.lot} ${los.escapedAliases.occupant} types.

    +
    + `; + return; + } + containerElement.innerHTML = ''; + for (const lotOccupantType of lotOccupantTypes) { + const tableRowElement = document.createElement('tr'); + tableRowElement.dataset.lotOccupantTypeId = + lotOccupantType.lotOccupantTypeId.toString(); + const formId = `form--lotOccupantType-${lotOccupantType.lotOccupantTypeId.toString()}`; + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` +
    +
    + +
    +
    + +
    +
    + fa- +
    +
    + +
    +
    + + + +
    +
    + +
    +
    + +
    +
    + +
    + + +
    + +
    +
    + ${los.getMoveUpDownButtonFieldHTML('button--moveLotOccupantTypeUp', 'button--moveLotOccupantTypeDown', false)} +
    +
    + +
    +
    + `; + const fontAwesomeInputElement = tableRowElement.querySelector("input[name='fontAwesomeIconClass']"); + fontAwesomeInputElement.addEventListener('keyup', refreshFontAwesomeIcon); + fontAwesomeInputElement.addEventListener('change', refreshFontAwesomeIcon); + tableRowElement + .querySelector('form') + ?.addEventListener('submit', updateLotOccupantType); + tableRowElement.querySelector('.button--moveLotOccupantTypeUp').addEventListener('click', moveLotOccupantType); + tableRowElement.querySelector('.button--moveLotOccupantTypeDown').addEventListener('click', moveLotOccupantType); + tableRowElement + .querySelector('.button--deleteLotOccupantType') + ?.addEventListener('click', deleteLotOccupantType); + containerElement.append(tableRowElement); + } + } + ; + document.querySelector('#form--addLotOccupantType').addEventListener('submit', (submitEvent) => { + submitEvent.preventDefault(); + const formElement = submitEvent.currentTarget; + cityssm.postJSON(`${los.urlPrefix}/admin/doAddLotOccupantType`, formElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes; + renderLotOccupantTypes(); + formElement.reset(); + formElement.querySelector('input')?.focus(); + } + else { + bulmaJS.alert({ + title: `Error Adding ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + }); + renderLotOccupantTypes(); + })(); +})(); diff --git a/public/javascripts/adminTables.min.js b/public/javascripts/adminTables.min.js deleted file mode 100644 index 86562322..00000000 --- a/public/javascripts/adminTables.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los;function t(e){var t;const s=e.currentTarget,o=s.value;(null===(t=s.closest(".field"))||void 0===t?void 0:t.querySelectorAll(".button.is-static"))[1].innerHTML=``}Object.defineProperty(exports,"__esModule",{value:!0});let s=exports.workOrderTypes;function o(t){t.preventDefault(),cityssm.postJSON(`${e.urlPrefix}/admin/doUpdateWorkOrderType`,t.currentTarget,e=>{var t;const o=e;o.success?(s=o.workOrderTypes,bulmaJS.alert({message:"Work Order Type Updated Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Updating Work Order Type",message:null!==(t=o.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}function r(t){const o=t.currentTarget.closest("tr"),r=o.dataset.workOrderTypeId;bulmaJS.confirm({title:"Delete Work Order Type",message:"Are you sure you want to delete this work order type?
    \n Note that no work orders will be removed.",messageIsHtml:!0,contextualColorName:"warning",okButton:{text:"Yes, Delete Work Order Type",callbackFunction:function(){cityssm.postJSON(`${e.urlPrefix}/admin/doDeleteWorkOrderType`,{workOrderTypeId:r},e=>{var t;const r=e;r.success?(0===(s=r.workOrderTypes).length?a():o.remove(),bulmaJS.alert({message:"Work Order Type Deleted Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Deleting Work Order Type",message:null!==(t=r.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}}})}function n(t){const o=t.currentTarget,r=o.closest("tr").dataset.workOrderTypeId;cityssm.postJSON(`${e.urlPrefix}/admin/${"up"===o.dataset.direction?"doMoveWorkOrderTypeUp":"doMoveWorkOrderTypeDown"}`,{workOrderTypeId:r,moveToEnd:t.shiftKey?"1":"0"},e=>{var t;const o=e;o.success?(s=o.workOrderTypes,a()):bulmaJS.alert({title:"Error Moving Work Order Type",message:null!==(t=o.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}function a(){var t,a,l;const c=document.querySelector("#container--workOrderTypes");if(0!==s.length){c.innerHTML="";for(const d of s){const s=document.createElement("tr");s.dataset.workOrderTypeId=d.workOrderTypeId.toString(),s.innerHTML=`\n
    \n \n
    \n
    \n \n
    \n
    \n \n
    \n
    \n
    \n \n
    \n
    \n ${e.getMoveUpDownButtonFieldHTML("button--moveWorkOrderTypeUp","button--moveWorkOrderTypeDown",!1)}\n
    \n
    \n \n
    \n
    \n `,null===(a=s.querySelector("form"))||void 0===a||a.addEventListener("submit",o),s.querySelector(".button--moveWorkOrderTypeUp").addEventListener("click",n),s.querySelector(".button--moveWorkOrderTypeDown").addEventListener("click",n),null===(l=s.querySelector(".button--deleteWorkOrderType"))||void 0===l||l.addEventListener("click",r),c.append(s)}}else c.innerHTML='\n

    There are no active work order types.

    \n '}delete exports.workOrderTypes,document.querySelector("#form--addWorkOrderType").addEventListener("submit",t=>{t.preventDefault();const o=t.currentTarget;cityssm.postJSON(`${e.urlPrefix}/admin/doAddWorkOrderType`,o,e=>{var t,r;const n=e;n.success?(s=n.workOrderTypes,a(),o.reset(),null===(t=o.querySelector("input"))||void 0===t||t.focus()):bulmaJS.alert({title:"Error Adding Work Order Type",message:null!==(r=n.errorMessage)&&void 0!==r?r:"",contextualColorName:"danger"})})}),a(),Object.defineProperty(exports,"__esModule",{value:!0});let l=exports.workOrderMilestoneTypes;function c(t){t.preventDefault(),cityssm.postJSON(`${e.urlPrefix}/admin/doUpdateWorkOrderMilestoneType`,t.currentTarget,e=>{var t;const s=e;s.success?(l=s.workOrderMilestoneTypes,bulmaJS.alert({message:"Work Order Milestone Type Updated Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Updating Work Order Milestone Type",message:null!==(t=s.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}function d(t){const s=t.currentTarget.closest("tr"),o=s.dataset.workOrderMilestoneTypeId;bulmaJS.confirm({title:"Delete Work Order Milestone Type",message:"Are you sure you want to delete this work order milestone type?
    \n Note that no work orders will be removed.",messageIsHtml:!0,contextualColorName:"warning",okButton:{text:"Yes, Delete Work Order Milestone Type",callbackFunction:function(){cityssm.postJSON(`${e.urlPrefix}/admin/doDeleteWorkOrderMilestoneType`,{workOrderMilestoneTypeId:o},e=>{var t;const o=e;o.success?(0===(l=o.workOrderMilestoneTypes).length?u():s.remove(),bulmaJS.alert({message:"Work Order Milestone Type Deleted Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Deleting Work Order Milestone Type",message:null!==(t=o.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}}})}function i(t){const s=t.currentTarget,o=s.closest("tr").dataset.workOrderMilestoneTypeId;cityssm.postJSON(`${e.urlPrefix}/admin/${"up"===s.dataset.direction?"doMoveWorkOrderMilestoneTypeUp":"doMoveWorkOrderMilestoneTypeDown"}`,{workOrderMilestoneTypeId:o,moveToEnd:t.shiftKey?"1":"0"},e=>{var t;const s=e;s.success?(l=s.workOrderMilestoneTypes,u()):bulmaJS.alert({title:"Error Moving Work Order Milestone Type",message:null!==(t=s.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}function u(){var t,s;const o=document.querySelector("#container--workOrderMilestoneTypes");if(0!==l.length){o.innerHTML="";for(const r of l){const n=document.createElement("tr");n.dataset.workOrderMilestoneTypeId=r.workOrderMilestoneTypeId.toString(),n.innerHTML=`\n
    \n \n
    \n
    \n \n
    \n
    \n \n
    \n
    \n
    \n \n
    \n
    \n ${e.getMoveUpDownButtonFieldHTML("button--moveWorkOrderMilestoneTypeUp","button--moveWorkOrderMilestoneTypeDown",!1)}\n
    \n
    \n \n
    \n
    \n `,null===(t=n.querySelector("form"))||void 0===t||t.addEventListener("submit",c),n.querySelector(".button--moveWorkOrderMilestoneTypeUp").addEventListener("click",i),n.querySelector(".button--moveWorkOrderMilestoneTypeDown").addEventListener("click",i),null===(s=n.querySelector(".button--deleteWorkOrderMilestoneType"))||void 0===s||s.addEventListener("click",d),o.append(n)}}else o.innerHTML='\n

    There are no active work order milestone types.

    \n '}delete exports.workOrderMilestoneTypes,document.querySelector("#form--addWorkOrderMilestoneType").addEventListener("submit",t=>{t.preventDefault();const s=t.currentTarget;cityssm.postJSON(`${e.urlPrefix}/admin/doAddWorkOrderMilestoneType`,s,e=>{var t,o;const r=e;r.success?(l=r.workOrderMilestoneTypes,u(),s.reset(),null===(t=s.querySelector("input"))||void 0===t||t.focus()):bulmaJS.alert({title:"Error Adding Work Order Milestone Type",message:null!==(o=r.errorMessage)&&void 0!==o?o:"",contextualColorName:"danger"})})}),u(),Object.defineProperty(exports,"__esModule",{value:!0});let p=exports.lotStatuses;function m(t){t.preventDefault(),cityssm.postJSON(`${e.urlPrefix}/admin/doUpdateLotStatus`,t.currentTarget,t=>{var s;const o=t;o.success?(p=o.lotStatuses,bulmaJS.alert({message:`${e.escapedAliases.Lot} Status Updated Successfully`,contextualColorName:"success"})):bulmaJS.alert({title:`Error Updating ${e.escapedAliases.Lot} Status`,message:null!==(s=o.errorMessage)&&void 0!==s?s:"",contextualColorName:"danger"})})}function y(t){const s=t.currentTarget.closest("tr"),o=s.dataset.lotStatusId;bulmaJS.confirm({title:`Delete ${e.escapedAliases.Lot} Status`,message:`Are you sure you want to delete this status?
    \n Note that no ${e.escapedAliases.lot} will be removed.`,messageIsHtml:!0,contextualColorName:"warning",okButton:{text:"Yes, Delete Status",callbackFunction:function(){cityssm.postJSON(`${e.urlPrefix}/admin/doDeleteLotStatus`,{lotStatusId:o},t=>{var o;const r=t;r.success?(0===(p=r.lotStatuses).length?T():s.remove(),bulmaJS.alert({message:`${e.escapedAliases.Lot} Status Deleted Successfully`,contextualColorName:"success"})):bulmaJS.alert({title:`Error Deleting ${e.escapedAliases.Lot} Status`,message:null!==(o=r.errorMessage)&&void 0!==o?o:"",contextualColorName:"danger"})})}}})}function v(t){const s=t.currentTarget,o=s.closest("tr").dataset.lotStatusId;cityssm.postJSON(`${e.urlPrefix}/admin/${"up"===s.dataset.direction?"doMoveLotStatusUp":"doMoveLotStatusDown"}`,{lotStatusId:o,moveToEnd:t.shiftKey?"1":"0"},t=>{var s;const o=t;o.success?(p=o.lotStatuses,T()):bulmaJS.alert({title:`Error Moving ${e.escapedAliases.Lot} Status`,message:null!==(s=o.errorMessage)&&void 0!==s?s:"",contextualColorName:"danger"})})}function T(){var t,s;const o=document.querySelector("#container--lotStatuses");if(0!==p.length){o.innerHTML="";for(const r of p){const n=document.createElement("tr");n.dataset.lotStatusId=r.lotStatusId.toString(),n.innerHTML=`\n
    \n \n
    \n
    \n \n
    \n
    \n \n
    \n
    \n
    \n \n
    \n
    \n ${e.getMoveUpDownButtonFieldHTML("button--moveLotStatusUp","button--moveLotStatusDown",!1)}\n
    \n
    \n \n
    \n
    \n `,null===(t=n.querySelector("form"))||void 0===t||t.addEventListener("submit",m),n.querySelector(".button--moveLotStatusUp").addEventListener("click",v),n.querySelector(".button--moveLotStatusDown").addEventListener("click",v),null===(s=n.querySelector(".button--deleteLotStatus"))||void 0===s||s.addEventListener("click",y),o.append(n)}}else o.innerHTML=`\n

    There are no active ${e.escapedAliases.lot} statuses.

    \n `}delete exports.lotStatuses,document.querySelector("#form--addLotStatus").addEventListener("submit",t=>{t.preventDefault();const s=t.currentTarget;cityssm.postJSON(`${e.urlPrefix}/admin/doAddLotStatus`,s,t=>{var o,r;const n=t;n.success?(p=n.lotStatuses,T(),s.reset(),null===(o=s.querySelector("input"))||void 0===o||o.focus()):bulmaJS.alert({title:`Error Adding ${e.escapedAliases.Lot} Status`,message:null!==(r=n.errorMessage)&&void 0!==r?r:"",contextualColorName:"danger"})})}),T(),Object.defineProperty(exports,"__esModule",{value:!0});let g=exports.lotOccupantTypes;function f(t){t.preventDefault(),cityssm.postJSON(`${e.urlPrefix}/admin/doUpdateLotOccupantType`,t.currentTarget,t=>{var s;const o=t;o.success?(g=o.lotOccupantTypes,bulmaJS.alert({message:`${e.escapedAliases.Lot} ${e.escapedAliases.Occupant} Type Updated Successfully`,contextualColorName:"success"})):bulmaJS.alert({title:`Error Updating ${e.escapedAliases.Lot} ${e.escapedAliases.Occupant} Type`,message:null!==(s=o.errorMessage)&&void 0!==s?s:"",contextualColorName:"danger"})})}function O(t){const s=t.currentTarget.closest("tr"),o=s.dataset.lotOccupantTypeId;bulmaJS.confirm({title:`Delete ${e.escapedAliases.Lot} ${e.escapedAliases.Occupant} Type`,message:`Are you sure you want to delete this ${e.escapedAliases.lot} ${e.escapedAliases.occupant} type?
    \n Note that no ${e.escapedAliases.lot} ${e.escapedAliases.occupants} will be removed.`,messageIsHtml:!0,contextualColorName:"warning",okButton:{text:`Yes, Delete ${e.escapedAliases.Lot} ${e.escapedAliases.Occupant} Type`,callbackFunction:function(){cityssm.postJSON(`${e.urlPrefix}/admin/doDeleteLotOccupantType`,{lotOccupantTypeId:o},t=>{var o;const r=t;r.success?(0===(g=r.lotOccupantTypes).length?b():s.remove(),bulmaJS.alert({message:`${e.escapedAliases.Lot} ${e.escapedAliases.Occupant} Type Deleted Successfully`,contextualColorName:"success"})):bulmaJS.alert({title:`Error Deleting ${e.escapedAliases.Lot} ${e.escapedAliases.Occupant} Type`,message:null!==(o=r.errorMessage)&&void 0!==o?o:"",contextualColorName:"danger"})})}}})}function S(t){const s=t.currentTarget,o=s.closest("tr").dataset.lotOccupantTypeId;cityssm.postJSON(`${e.urlPrefix}/admin/${"up"===s.dataset.direction?"doMoveLotOccupantTypeUp":"doMoveLotOccupantTypeDown"}`,{lotOccupantTypeId:o,moveToEnd:t.shiftKey?"1":"0"},t=>{var s;const o=t;o.success?(g=o.lotOccupantTypes,b()):bulmaJS.alert({title:`Error Moving ${e.escapedAliases.Lot} ${e.escapedAliases.Occupant} Type`,message:null!==(s=o.errorMessage)&&void 0!==s?s:"",contextualColorName:"danger"})})}function b(){var s,o;const r=document.querySelector("#container--lotOccupantTypes");if(0!==g.length){r.innerHTML="";for(const n of g){const a=document.createElement("tr");a.dataset.lotOccupantTypeId=n.lotOccupantTypeId.toString();const l=`form--lotOccupantType-${n.lotOccupantTypeId.toString()}`;a.innerHTML=`\n
    \n
    \n \n
    \n
    \n \n
    \n
    \n fa-\n
    \n
    \n \n
    \n
    \n \n \n \n
    \n
    \n \n
    \n
    \n \n
    \n
    \n \n
    \n \n \n
    \n \n
    \n
    \n ${e.getMoveUpDownButtonFieldHTML("button--moveLotOccupantTypeUp","button--moveLotOccupantTypeDown",!1)}\n
    \n
    \n \n
    \n
    \n `;const c=a.querySelector("input[name='fontAwesomeIconClass']");c.addEventListener("keyup",t),c.addEventListener("change",t),null===(s=a.querySelector("form"))||void 0===s||s.addEventListener("submit",f),a.querySelector(".button--moveLotOccupantTypeUp").addEventListener("click",S),a.querySelector(".button--moveLotOccupantTypeDown").addEventListener("click",S),null===(o=a.querySelector(".button--deleteLotOccupantType"))||void 0===o||o.addEventListener("click",O),r.append(a)}}else r.innerHTML=`\n
    \n

    There are no active ${e.escapedAliases.lot} ${e.escapedAliases.occupant} types.

    \n
    \n `}delete exports.lotOccupantTypes,document.querySelector("#form--addLotOccupantType").addEventListener("submit",t=>{t.preventDefault();const s=t.currentTarget;cityssm.postJSON(`${e.urlPrefix}/admin/doAddLotOccupantType`,s,t=>{var o,r;const n=t;n.success?(g=n.lotOccupantTypes,b(),s.reset(),null===(o=s.querySelector("input"))||void 0===o||o.focus()):bulmaJS.alert({title:`Error Adding ${e.escapedAliases.Lot} ${e.escapedAliases.Occupant} Type`,message:null!==(r=n.errorMessage)&&void 0!==r?r:"",contextualColorName:"danger"})})}),b()})(); \ No newline at end of file diff --git a/public/javascripts/adminTables.ts b/public/javascripts/adminTables.ts new file mode 100644 index 00000000..39910a01 --- /dev/null +++ b/public/javascripts/adminTables.ts @@ -0,0 +1,1043 @@ +// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair +/* eslint-disable unicorn/prefer-module */ + +import type { BulmaJS } from '@cityssm/bulma-js/types.js' +import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' + +import type { LOS } from '../../types/globalTypes.js' +import type { + LotOccupantType, + LotStatus, + WorkOrderMilestoneType, + WorkOrderType +} from '../../types/recordTypes.js' + +declare const exports: Record + +declare const cityssm: cityssmGlobal +declare const bulmaJS: BulmaJS +;(() => { + const los = exports.los as LOS + + function refreshFontAwesomeIcon(changeEvent: Event): void { + const inputElement = changeEvent.currentTarget as HTMLInputElement + + const fontAwesomeIconClass = inputElement.value + + // eslint-disable-next-line no-unsanitized/property + ;( + inputElement.closest('.field')?.querySelectorAll( + '.button.is-static' + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + ) as NodeListOf + )[1].innerHTML = + `` + } + + /** + * Work Order Types + */ + ;(() => { + let workOrderTypes = exports.workOrderTypes as WorkOrderType[] + delete exports.workOrderTypes + + type ResponseJSON = + | { + success: true + workOrderTypes: WorkOrderType[] + } + | { + success: false + errorMessage: string + } + + function updateWorkOrderType(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/admin/doUpdateWorkOrderType`, + submitEvent.currentTarget, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + workOrderTypes = responseJSON.workOrderTypes + + bulmaJS.alert({ + message: 'Work Order Type Updated Successfully', + contextualColorName: 'success' + }) + } else { + bulmaJS.alert({ + title: 'Error Updating Work Order Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + function deleteWorkOrderType(clickEvent: Event): void { + const tableRowElement = (clickEvent.currentTarget as HTMLElement).closest( + 'tr' + ) as HTMLTableRowElement + + const workOrderTypeId = tableRowElement.dataset.workOrderTypeId + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/admin/doDeleteWorkOrderType`, + { + workOrderTypeId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + workOrderTypes = responseJSON.workOrderTypes + + if (workOrderTypes.length === 0) { + renderWorkOrderTypes() + } else { + tableRowElement.remove() + } + + bulmaJS.alert({ + message: 'Work Order Type Deleted Successfully', + contextualColorName: 'success' + }) + } else { + bulmaJS.alert({ + title: 'Error Deleting Work Order Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + bulmaJS.confirm({ + title: 'Delete Work Order Type', + message: `Are you sure you want to delete this work order type?
    + Note that no work orders will be removed.`, + messageIsHtml: true, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Work Order Type', + callbackFunction: doDelete + } + }) + } + + function moveWorkOrderType(clickEvent: MouseEvent): void { + const buttonElement = clickEvent.currentTarget as HTMLButtonElement + + const tableRowElement = buttonElement.closest('tr') as HTMLTableRowElement + + const workOrderTypeId = tableRowElement.dataset.workOrderTypeId + + cityssm.postJSON( + `${los.urlPrefix}/admin/${ + buttonElement.dataset.direction === 'up' + ? 'doMoveWorkOrderTypeUp' + : 'doMoveWorkOrderTypeDown' + }`, + { + workOrderTypeId, + moveToEnd: clickEvent.shiftKey ? '1' : '0' + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + workOrderTypes = responseJSON.workOrderTypes + renderWorkOrderTypes() + } else { + bulmaJS.alert({ + title: 'Error Moving Work Order Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + function renderWorkOrderTypes(): void { + const containerElement = document.querySelector( + '#container--workOrderTypes' + ) as HTMLTableSectionElement + + if (workOrderTypes.length === 0) { + containerElement.innerHTML = ` +

    There are no active work order types.

    + ` + + return + } + + containerElement.innerHTML = '' + + for (const workOrderType of workOrderTypes) { + const tableRowElement = document.createElement('tr') + + tableRowElement.dataset.workOrderTypeId = + workOrderType.workOrderTypeId.toString() + + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + ${los.getMoveUpDownButtonFieldHTML( + 'button--moveWorkOrderTypeUp', + 'button--moveWorkOrderTypeDown', + false + )} +
    +
    + +
    +
    + ` + + tableRowElement + .querySelector('form') + ?.addEventListener('submit', updateWorkOrderType) + ;( + tableRowElement.querySelector( + '.button--moveWorkOrderTypeUp' + ) as HTMLButtonElement + ).addEventListener('click', moveWorkOrderType) + ;( + tableRowElement.querySelector( + '.button--moveWorkOrderTypeDown' + ) as HTMLButtonElement + ).addEventListener('click', moveWorkOrderType) + + tableRowElement + .querySelector('.button--deleteWorkOrderType') + ?.addEventListener('click', deleteWorkOrderType) + + containerElement.append(tableRowElement) + } + } + ;( + document.querySelector('#form--addWorkOrderType') as HTMLFormElement + ).addEventListener('submit', (submitEvent: SubmitEvent) => { + submitEvent.preventDefault() + + const formElement = submitEvent.currentTarget as HTMLFormElement + + cityssm.postJSON( + `${los.urlPrefix}/admin/doAddWorkOrderType`, + formElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + workOrderTypes = responseJSON.workOrderTypes + renderWorkOrderTypes() + formElement.reset() + formElement.querySelector('input')?.focus() + } else { + bulmaJS.alert({ + title: 'Error Adding Work Order Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + }) + + renderWorkOrderTypes() + })() + + /** + * Work Order Milestone Types + */ + ;(() => { + let workOrderMilestoneTypes = + exports.workOrderMilestoneTypes as WorkOrderMilestoneType[] + delete exports.workOrderMilestoneTypes + + type ResponseJSON = + | { + success: true + workOrderMilestoneTypes: WorkOrderMilestoneType[] + } + | { + success: false + errorMessage: string + } + + function updateWorkOrderMilestoneType(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/admin/doUpdateWorkOrderMilestoneType`, + submitEvent.currentTarget, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes + + bulmaJS.alert({ + message: 'Work Order Milestone Type Updated Successfully', + contextualColorName: 'success' + }) + } else { + bulmaJS.alert({ + title: 'Error Updating Work Order Milestone Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + function deleteWorkOrderMilestoneType(clickEvent: Event): void { + const tableRowElement = (clickEvent.currentTarget as HTMLElement).closest( + 'tr' + ) as HTMLTableRowElement + + const workOrderMilestoneTypeId = + tableRowElement.dataset.workOrderMilestoneTypeId + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/admin/doDeleteWorkOrderMilestoneType`, + { + workOrderMilestoneTypeId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes + + if (workOrderMilestoneTypes.length === 0) { + renderWorkOrderMilestoneTypes() + } else { + tableRowElement.remove() + } + + bulmaJS.alert({ + message: 'Work Order Milestone Type Deleted Successfully', + contextualColorName: 'success' + }) + } else { + bulmaJS.alert({ + title: 'Error Deleting Work Order Milestone Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + bulmaJS.confirm({ + title: 'Delete Work Order Milestone Type', + message: `Are you sure you want to delete this work order milestone type?
    + Note that no work orders will be removed.`, + messageIsHtml: true, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Work Order Milestone Type', + callbackFunction: doDelete + } + }) + } + + function moveWorkOrderMilestoneType(clickEvent: MouseEvent): void { + const buttonElement = clickEvent.currentTarget as HTMLButtonElement + + const tableRowElement = buttonElement.closest('tr') as HTMLTableRowElement + + const workOrderMilestoneTypeId = + tableRowElement.dataset.workOrderMilestoneTypeId + + cityssm.postJSON( + `${los.urlPrefix}/admin/${ + buttonElement.dataset.direction === 'up' + ? 'doMoveWorkOrderMilestoneTypeUp' + : 'doMoveWorkOrderMilestoneTypeDown' + }`, + { + workOrderMilestoneTypeId, + moveToEnd: clickEvent.shiftKey ? '1' : '0' + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes + renderWorkOrderMilestoneTypes() + } else { + bulmaJS.alert({ + title: 'Error Moving Work Order Milestone Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + function renderWorkOrderMilestoneTypes(): void { + const containerElement = document.querySelector( + '#container--workOrderMilestoneTypes' + ) as HTMLTableSectionElement + + if (workOrderMilestoneTypes.length === 0) { + containerElement.innerHTML = ` +

    There are no active work order milestone types.

    + ` + + return + } + + containerElement.innerHTML = '' + + for (const workOrderMilestoneType of workOrderMilestoneTypes) { + const tableRowElement = document.createElement('tr') + + tableRowElement.dataset.workOrderMilestoneTypeId = + workOrderMilestoneType.workOrderMilestoneTypeId.toString() + + // eslint-disable-next-line no-unsanitized/property, no-secrets/no-secrets + tableRowElement.innerHTML = ` +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + ${los.getMoveUpDownButtonFieldHTML( + 'button--moveWorkOrderMilestoneTypeUp', + 'button--moveWorkOrderMilestoneTypeDown', + false + )} +
    +
    + +
    +
    + ` + + tableRowElement + .querySelector('form') + ?.addEventListener('submit', updateWorkOrderMilestoneType) + ;( + tableRowElement.querySelector( + '.button--moveWorkOrderMilestoneTypeUp' + ) as HTMLButtonElement + ).addEventListener('click', moveWorkOrderMilestoneType) + ;( + tableRowElement.querySelector( + '.button--moveWorkOrderMilestoneTypeDown' + ) as HTMLButtonElement + ).addEventListener('click', moveWorkOrderMilestoneType) + + tableRowElement + .querySelector('.button--deleteWorkOrderMilestoneType') + ?.addEventListener('click', deleteWorkOrderMilestoneType) + + containerElement.append(tableRowElement) + } + } + ;( + document.querySelector( + '#form--addWorkOrderMilestoneType' + ) as HTMLFormElement + ).addEventListener('submit', (submitEvent: SubmitEvent) => { + submitEvent.preventDefault() + + const formElement = submitEvent.currentTarget as HTMLFormElement + + cityssm.postJSON( + `${los.urlPrefix}/admin/doAddWorkOrderMilestoneType`, + formElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + workOrderMilestoneTypes = responseJSON.workOrderMilestoneTypes + renderWorkOrderMilestoneTypes() + formElement.reset() + formElement.querySelector('input')?.focus() + } else { + bulmaJS.alert({ + title: 'Error Adding Work Order Milestone Type', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + }) + + renderWorkOrderMilestoneTypes() + })() + + /** + * Lot Statuses + */ + ;(() => { + let lotStatuses = exports.lotStatuses as LotStatus[] + delete exports.lotStatuses + + type ResponseJSON = + | { + success: true + lotStatuses: LotStatus[] + } + | { + success: false + errorMessage: string + } + + function updateLotStatus(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/admin/doUpdateLotStatus`, + submitEvent.currentTarget, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + lotStatuses = responseJSON.lotStatuses + + bulmaJS.alert({ + message: `${los.escapedAliases.Lot} Status Updated Successfully`, + contextualColorName: 'success' + }) + } else { + bulmaJS.alert({ + title: `Error Updating ${los.escapedAliases.Lot} Status`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + function deleteLotStatus(clickEvent: Event): void { + const tableRowElement = (clickEvent.currentTarget as HTMLElement).closest( + 'tr' + ) as HTMLTableRowElement + + const lotStatusId = tableRowElement.dataset.lotStatusId + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/admin/doDeleteLotStatus`, + { + lotStatusId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + lotStatuses = responseJSON.lotStatuses + + if (lotStatuses.length === 0) { + renderLotStatuses() + } else { + tableRowElement.remove() + } + + bulmaJS.alert({ + message: `${los.escapedAliases.Lot} Status Deleted Successfully`, + contextualColorName: 'success' + }) + } else { + bulmaJS.alert({ + title: `Error Deleting ${los.escapedAliases.Lot} Status`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + bulmaJS.confirm({ + title: `Delete ${los.escapedAliases.Lot} Status`, + message: `Are you sure you want to delete this status?
    + Note that no ${los.escapedAliases.lot} will be removed.`, + messageIsHtml: true, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Status', + callbackFunction: doDelete + } + }) + } + + function moveLotStatus(clickEvent: MouseEvent): void { + const buttonElement = clickEvent.currentTarget as HTMLButtonElement + + const tableRowElement = buttonElement.closest('tr') as HTMLTableRowElement + + const lotStatusId = tableRowElement.dataset.lotStatusId + + cityssm.postJSON( + `${los.urlPrefix}/admin/${ + buttonElement.dataset.direction === 'up' + ? 'doMoveLotStatusUp' + : 'doMoveLotStatusDown' + }`, + { + lotStatusId, + moveToEnd: clickEvent.shiftKey ? '1' : '0' + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + lotStatuses = responseJSON.lotStatuses + renderLotStatuses() + } else { + bulmaJS.alert({ + title: `Error Moving ${los.escapedAliases.Lot} Status`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + function renderLotStatuses(): void { + const containerElement = document.querySelector( + '#container--lotStatuses' + ) as HTMLTableSectionElement + + if (lotStatuses.length === 0) { + // eslint-disable-next-line no-unsanitized/property + containerElement.innerHTML = ` +

    There are no active ${los.escapedAliases.lot} statuses.

    + ` + + return + } + + containerElement.innerHTML = '' + + for (const lotStatus of lotStatuses) { + const tableRowElement = document.createElement('tr') + + tableRowElement.dataset.lotStatusId = lotStatus.lotStatusId.toString() + + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` +
    + +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    + ${los.getMoveUpDownButtonFieldHTML( + 'button--moveLotStatusUp', + 'button--moveLotStatusDown', + false + )} +
    +
    + +
    +
    + ` + + tableRowElement + .querySelector('form') + ?.addEventListener('submit', updateLotStatus) + ;( + tableRowElement.querySelector( + '.button--moveLotStatusUp' + ) as HTMLButtonElement + ).addEventListener('click', moveLotStatus) + ;( + tableRowElement.querySelector( + '.button--moveLotStatusDown' + ) as HTMLButtonElement + ).addEventListener('click', moveLotStatus) + + tableRowElement + .querySelector('.button--deleteLotStatus') + ?.addEventListener('click', deleteLotStatus) + + containerElement.append(tableRowElement) + } + } + ;( + document.querySelector('#form--addLotStatus') as HTMLFormElement + ).addEventListener('submit', (submitEvent: SubmitEvent) => { + submitEvent.preventDefault() + + const formElement = submitEvent.currentTarget as HTMLFormElement + + cityssm.postJSON( + `${los.urlPrefix}/admin/doAddLotStatus`, + formElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + lotStatuses = responseJSON.lotStatuses + renderLotStatuses() + formElement.reset() + formElement.querySelector('input')?.focus() + } else { + bulmaJS.alert({ + title: `Error Adding ${los.escapedAliases.Lot} Status`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + }) + + renderLotStatuses() + })() + + /** + * Lot Occupant Types + */ + ;(() => { + let lotOccupantTypes = exports.lotOccupantTypes as LotOccupantType[] + delete exports.lotOccupantTypes + + type ResponseJSON = + | { + success: true + lotOccupantTypes: LotOccupantType[] + } + | { + success: false + errorMessage: string + } + + function updateLotOccupantType(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/admin/doUpdateLotOccupantType`, + submitEvent.currentTarget, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes + + bulmaJS.alert({ + message: `${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type Updated Successfully`, + contextualColorName: 'success' + }) + } else { + bulmaJS.alert({ + title: `Error Updating ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + function deleteLotOccupantType(clickEvent: Event): void { + const tableRowElement = (clickEvent.currentTarget as HTMLElement).closest( + 'tr' + ) as HTMLTableRowElement + + const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/admin/doDeleteLotOccupantType`, + { + lotOccupantTypeId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes + + if (lotOccupantTypes.length === 0) { + renderLotOccupantTypes() + } else { + tableRowElement.remove() + } + + bulmaJS.alert({ + message: `${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type Deleted Successfully`, + contextualColorName: 'success' + }) + } else { + bulmaJS.alert({ + title: `Error Deleting ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + bulmaJS.confirm({ + title: `Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, + message: `Are you sure you want to delete this ${los.escapedAliases.lot} ${los.escapedAliases.occupant} type?
    + Note that no ${los.escapedAliases.lot} ${los.escapedAliases.occupants} will be removed.`, + messageIsHtml: true, + contextualColorName: 'warning', + okButton: { + text: `Yes, Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, + callbackFunction: doDelete + } + }) + } + + function moveLotOccupantType(clickEvent: MouseEvent): void { + const buttonElement = clickEvent.currentTarget as HTMLButtonElement + + const tableRowElement = buttonElement.closest('tr') as HTMLTableRowElement + + const lotOccupantTypeId = tableRowElement.dataset.lotOccupantTypeId + + cityssm.postJSON( + `${los.urlPrefix}/admin/${ + buttonElement.dataset.direction === 'up' + ? 'doMoveLotOccupantTypeUp' + : 'doMoveLotOccupantTypeDown' + }`, + { + lotOccupantTypeId, + moveToEnd: clickEvent.shiftKey ? '1' : '0' + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes + renderLotOccupantTypes() + } else { + bulmaJS.alert({ + title: `Error Moving ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + function renderLotOccupantTypes(): void { + const containerElement = document.querySelector( + '#container--lotOccupantTypes' + ) as HTMLTableSectionElement + + if (lotOccupantTypes.length === 0) { + // eslint-disable-next-line no-unsanitized/property + containerElement.innerHTML = ` +
    +

    There are no active ${los.escapedAliases.lot} ${los.escapedAliases.occupant} types.

    +
    + ` + + return + } + + containerElement.innerHTML = '' + + for (const lotOccupantType of lotOccupantTypes) { + const tableRowElement = document.createElement('tr') + + tableRowElement.dataset.lotOccupantTypeId = + lotOccupantType.lotOccupantTypeId.toString() + + const formId = `form--lotOccupantType-${lotOccupantType.lotOccupantTypeId.toString()}` + + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` +
    +
    + +
    +
    + +
    +
    + fa- +
    +
    + +
    +
    + + + +
    +
    + +
    +
    + +
    +
    + +
    + + +
    + +
    +
    + ${los.getMoveUpDownButtonFieldHTML( + 'button--moveLotOccupantTypeUp', + 'button--moveLotOccupantTypeDown', + false + )} +
    +
    + +
    +
    + ` + + const fontAwesomeInputElement = tableRowElement.querySelector( + "input[name='fontAwesomeIconClass']" + ) as HTMLInputElement + + fontAwesomeInputElement.addEventListener( + 'keyup', + refreshFontAwesomeIcon + ) + fontAwesomeInputElement.addEventListener( + 'change', + refreshFontAwesomeIcon + ) + + tableRowElement + .querySelector('form') + ?.addEventListener('submit', updateLotOccupantType) + ;( + tableRowElement.querySelector( + '.button--moveLotOccupantTypeUp' + ) as HTMLButtonElement + ).addEventListener('click', moveLotOccupantType) + ;( + tableRowElement.querySelector( + '.button--moveLotOccupantTypeDown' + ) as HTMLButtonElement + ).addEventListener('click', moveLotOccupantType) + + tableRowElement + .querySelector('.button--deleteLotOccupantType') + ?.addEventListener('click', deleteLotOccupantType) + + containerElement.append(tableRowElement) + } + } + ;( + document.querySelector('#form--addLotOccupantType') as HTMLFormElement + ).addEventListener('submit', (submitEvent: SubmitEvent) => { + submitEvent.preventDefault() + + const formElement = submitEvent.currentTarget as HTMLFormElement + + cityssm.postJSON( + `${los.urlPrefix}/admin/doAddLotOccupantType`, + formElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as ResponseJSON + + if (responseJSON.success) { + lotOccupantTypes = responseJSON.lotOccupantTypes + renderLotOccupantTypes() + formElement.reset() + formElement.querySelector('input')?.focus() + } else { + bulmaJS.alert({ + title: `Error Adding ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + }) + + renderLotOccupantTypes() + })() +})() diff --git a/public-typescript/dashboard.d.ts b/public/javascripts/dashboard.d.ts similarity index 100% rename from public-typescript/dashboard.d.ts rename to public/javascripts/dashboard.d.ts diff --git a/public-typescript/dashboard.js b/public/javascripts/dashboard.js similarity index 100% rename from public-typescript/dashboard.js rename to public/javascripts/dashboard.js diff --git a/public/javascripts/dashboard.min.js b/public/javascripts/dashboard.min.js deleted file mode 100644 index 3138af00..00000000 --- a/public/javascripts/dashboard.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e;const o=exports.los,r=document.querySelectorAll(".fa-circle[data-work-order-number]");for(const t of r)t.style.color=o.getRandomColor(null!==(e=t.dataset.workOrderNumber)&&void 0!==e?e:"")})(); \ No newline at end of file diff --git a/public-typescript/dashboard.ts b/public/javascripts/dashboard.ts similarity index 91% rename from public-typescript/dashboard.ts rename to public/javascripts/dashboard.ts index eaa8f232..c14e7940 100644 --- a/public-typescript/dashboard.ts +++ b/public/javascripts/dashboard.ts @@ -1,7 +1,7 @@ // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair /* eslint-disable unicorn/prefer-module */ -import type { LOS } from '../types/globalTypes.js' +import type { LOS } from '../../types/globalTypes.js' declare const exports: Record ;(() => { diff --git a/public-typescript/lotEdit.d.ts b/public/javascripts/lotEdit.d.ts similarity index 100% rename from public-typescript/lotEdit.d.ts rename to public/javascripts/lotEdit.d.ts diff --git a/public-typescript/lotEdit.js b/public/javascripts/lotEdit.js similarity index 100% rename from public-typescript/lotEdit.js rename to public/javascripts/lotEdit.js diff --git a/public/javascripts/lotEdit.min.js b/public/javascripts/lotEdit.min.js deleted file mode 100644 index 176ff2c0..00000000 --- a/public/javascripts/lotEdit.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e,t;const o=exports.los,n=document.querySelector("#lot--lotId").value,l=""===n;let s=l;function a(){var e;o.setUnsavedChanges(),null===(e=document.querySelector("button[type='submit'][form='form--lot']"))||void 0===e||e.classList.remove("is-light")}function i(){var e;o.clearUnsavedChanges(),null===(e=document.querySelector("button[type='submit'][form='form--lot']"))||void 0===e||e.classList.add("is-light")}const r=document.querySelector("#form--lot");r.addEventListener("submit",function(e){e.preventDefault(),cityssm.postJSON(`${o.urlPrefix}/lots/${l?"doCreateLot":"doUpdateLot"}`,r,e=>{var t;const n=e;n.success?(i(),l||s?window.location.href=o.getLotURL(n.lotId,!0,!0):bulmaJS.alert({message:`${o.escapedAliases.Lot} Updated Successfully`,contextualColorName:"success"})):bulmaJS.alert({title:`Error Updating ${o.escapedAliases.Lot}`,message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})});const d=r.querySelectorAll("input, select");for(const e of d)e.addEventListener("change",a);o.initializeUnlockFieldButtons(r),null===(e=document.querySelector("#button--deleteLot"))||void 0===e||e.addEventListener("click",e=>{e.preventDefault(),bulmaJS.confirm({title:`Delete ${o.escapedAliases.Lot}`,message:`Are you sure you want to delete this ${o.escapedAliases.lot}?`,contextualColorName:"warning",okButton:{text:`Yes, Delete ${o.escapedAliases.Lot}`,callbackFunction:function(){cityssm.postJSON(`${o.urlPrefix}/lots/doDeleteLot`,{lotId:n},e=>{var t;const n=e;n.success?(i(),window.location.href=o.getLotURL()):bulmaJS.alert({title:`Error Deleting ${o.escapedAliases.Lot}`,message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}}})});const m=document.querySelector("#lot--lotTypeId");if(l){const e=document.querySelector("#container--lotFields");m.addEventListener("change",()=>{""!==m.value?cityssm.postJSON(`${o.urlPrefix}/lots/doGetLotTypeFields`,{lotTypeId:m.value},t=>{var n,l,s;const a=t;if(0===a.lotTypeFields.length)return void(e.innerHTML=`
    \n

    \n There are no additional fields for this ${o.escapedAliases.lot} type.\n

    \n
    `);e.innerHTML="";let i="";for(const t of a.lotTypeFields){i+=`,${t.lotTypeFieldId.toString()}`;const o=`lotFieldValue_${t.lotTypeFieldId.toString()}`,a=`lot--${o}`,r=document.createElement("div");if(r.className="field",r.innerHTML=`\n
    `,r.querySelector("label").textContent=t.lotTypeField,""===t.lotTypeFieldValues){const e=document.createElement("input");e.className="input",e.id=a,e.name=o,e.type="text",e.required=t.isRequired,e.minLength=t.minimumLength,e.maxLength=t.maximumLength,""!==(null!==(n=t.pattern)&&void 0!==n?n:"")&&(e.pattern=null!==(l=t.pattern)&&void 0!==l?l:""),null===(s=r.querySelector(".control"))||void 0===s||s.append(e)}else{r.querySelector(".control").innerHTML=`
    \n \n
    `;const e=r.querySelector("select");e.required=t.isRequired;const n=t.lotTypeFieldValues.split("\n");for(const t of n){const o=document.createElement("option");o.value=t,o.textContent=t,e.append(o)}}e.append(r)}e.insertAdjacentHTML("beforeend",``)}):e.innerHTML=`
    \n

    Select the ${o.escapedAliases.lot} type to load the available fields.

    \n
    `})}else{const e=m.value;m.addEventListener("change",()=>{m.value!==e&&bulmaJS.confirm({title:"Confirm Change",message:`Are you sure you want to change the ${o.escapedAliases.lot} type?\n\n This change affects the additional fields associated with this record.`,contextualColorName:"warning",okButton:{text:"Yes, Keep the Change",callbackFunction(){s=!0}},cancelButton:{text:"Revert the Change",callbackFunction(){m.value=e}}})})}let c=exports.lotComments;function u(e){var t,l;const s=Number.parseInt(null!==(l=null===(t=e.currentTarget.closest("tr"))||void 0===t?void 0:t.dataset.lotCommentId)&&void 0!==l?l:"",10),a=c.find(e=>e.lotCommentId===s);let i,r;function d(e){e.preventDefault(),cityssm.postJSON(`${o.urlPrefix}/lots/doUpdateLotComment`,i,e=>{var t;const o=e;o.success?(c=o.lotComments,r(),v()):bulmaJS.alert({title:"Error Updating Comment",message:null!==(t=o.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}cityssm.openHtmlModal("lot-editComment",{onshow(e){var t,l,i,r;o.populateAliases(e),e.querySelector("#lotCommentEdit--lotId").value=n,e.querySelector("#lotCommentEdit--lotCommentId").value=s.toString(),e.querySelector("#lotCommentEdit--lotComment").value=null!==(t=a.lotComment)&&void 0!==t?t:"";const d=e.querySelector("#lotCommentEdit--lotCommentDateString");d.value=null!==(l=a.lotCommentDateString)&&void 0!==l?l:"";const m=cityssm.dateToString(new Date);d.max=a.lotCommentDateString<=m?m:null!==(i=a.lotCommentDateString)&&void 0!==i?i:"",e.querySelector("#lotCommentEdit--lotCommentTimeString").value=null!==(r=a.lotCommentTimeString)&&void 0!==r?r:""},onshown(e,t){bulmaJS.toggleHtmlClipped(),o.initializeDatePickers(e),e.querySelector("#lotCommentEdit--lotComment").focus(),(i=e.querySelector("form")).addEventListener("submit",d),r=t},onremoved(){bulmaJS.toggleHtmlClipped()}})}function p(e){var t,l;const s=Number.parseInt(null!==(l=null===(t=e.currentTarget.closest("tr"))||void 0===t?void 0:t.dataset.lotCommentId)&&void 0!==l?l:"",10);bulmaJS.confirm({title:"Remove Comment?",message:"Are you sure you want to remove this comment?",okButton:{text:"Yes, Remove Comment",callbackFunction:function(){cityssm.postJSON(`${o.urlPrefix}/lots/doDeleteLotComment`,{lotId:n,lotCommentId:s},e=>{var t;const o=e;o.success?(c=o.lotComments,v()):bulmaJS.alert({title:"Error Removing Comment",message:null!==(t=o.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}},contextualColorName:"warning"})}function v(){var e,t,o,n,l,s;const a=document.querySelector("#container--lotComments");if(0===c.length)return void(a.innerHTML='
    \n

    There are no comments to display.

    \n
    ');const i=document.createElement("table");i.className="table is-fullwidth is-striped is-hoverable",i.innerHTML='\n Commentor\n Comment Date\n Comment\n Options\n \n ';for(const a of c){const r=document.createElement("tr");r.dataset.lotCommentId=null===(e=a.lotCommentId)||void 0===e?void 0:e.toString(),r.innerHTML=`\n ${cityssm.escapeHTML(null!==(t=a.recordCreate_userName)&&void 0!==t?t:"")}\n \n ${a.lotCommentDateString}\n ${0===a.lotCommentTime?"":` ${a.lotCommentTimePeriodString}`}\n \n ${cityssm.escapeHTML(null!==(o=a.lotComment)&&void 0!==o?o:"")}\n \n
    \n \n \n
    \n `,null===(n=r.querySelector(".button--edit"))||void 0===n||n.addEventListener("click",u),null===(l=r.querySelector(".button--delete"))||void 0===l||l.addEventListener("click",p),null===(s=i.querySelector("tbody"))||void 0===s||s.append(r)}a.innerHTML="",a.append(i)}delete exports.lotComments,l||(null===(t=document.querySelector("#lotComments--add"))||void 0===t||t.addEventListener("click",function(){let e;function t(t){t.preventDefault(),cityssm.postJSON(`${o.urlPrefix}/lots/doAddLotComment`,t.currentTarget,t=>{const o=t;o.success&&(c=o.lotComments,v(),e())})}cityssm.openHtmlModal("lot-addComment",{onshow(e){var l;o.populateAliases(e),e.querySelector("#lotCommentAdd--lotId").value=n,null===(l=e.querySelector("form"))||void 0===l||l.addEventListener("submit",t)},onshown(t,o){bulmaJS.toggleHtmlClipped(),e=o,t.querySelector("#lotCommentAdd--lotComment").focus()},onremoved(){bulmaJS.toggleHtmlClipped(),document.querySelector("#lotComments--add").focus()}})}),v())})(); \ No newline at end of file diff --git a/public-typescript/lotEdit.ts b/public/javascripts/lotEdit.ts similarity index 99% rename from public-typescript/lotEdit.ts rename to public/javascripts/lotEdit.ts index 6a52850d..2bd3055d 100644 --- a/public-typescript/lotEdit.ts +++ b/public/javascripts/lotEdit.ts @@ -4,8 +4,8 @@ import type { BulmaJS } from '@cityssm/bulma-js/types.js' import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' -import type { LOS } from '../types/globalTypes.js' -import type { LotComment, LotTypeField } from '../types/recordTypes.js' +import type { LOS } from '../../types/globalTypes.js' +import type { LotComment, LotTypeField } from '../../types/recordTypes.js' declare const cityssm: cityssmGlobal declare const bulmaJS: BulmaJS diff --git a/public-typescript/lotOccupancyEdit/lotOccupancyEdit.d.ts b/public/javascripts/lotOccupancyEdit.d.ts similarity index 100% rename from public-typescript/lotOccupancyEdit/lotOccupancyEdit.d.ts rename to public/javascripts/lotOccupancyEdit.d.ts diff --git a/public/javascripts/lotOccupancyEdit.js b/public/javascripts/lotOccupancyEdit.js new file mode 100644 index 00000000..375b4164 --- /dev/null +++ b/public/javascripts/lotOccupancyEdit.js @@ -0,0 +1,1736 @@ +"use strict"; +/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */ +/* eslint-disable unicorn/prefer-module */ +Object.defineProperty(exports, "__esModule", { value: true }); +(() => { + const los = exports.los; + const lotOccupancyId = document.querySelector('#lotOccupancy--lotOccupancyId').value; + const isCreate = lotOccupancyId === ''; + /* + * Main form + */ + let refreshAfterSave = isCreate; + function setUnsavedChanges() { + los.setUnsavedChanges(); + document + .querySelector("button[type='submit'][form='form--lotOccupancy']") + ?.classList.remove('is-light'); + } + function clearUnsavedChanges() { + los.clearUnsavedChanges(); + document + .querySelector("button[type='submit'][form='form--lotOccupancy']") + ?.classList.add('is-light'); + } + const formElement = document.querySelector('#form--lotOccupancy'); + formElement.addEventListener('submit', (formEvent) => { + formEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/${isCreate ? 'doCreateLotOccupancy' : 'doUpdateLotOccupancy'}`, formElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + clearUnsavedChanges(); + if (isCreate || refreshAfterSave) { + window.location.href = los.getLotOccupancyURL(responseJSON.lotOccupancyId, true, true); + } + else { + bulmaJS.alert({ + message: `${los.escapedAliases.Occupancy} Updated Successfully`, + contextualColorName: 'success' + }); + } + } + else { + bulmaJS.alert({ + title: `Error Saving ${los.escapedAliases.Occupancy}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + }); + const formInputElements = formElement.querySelectorAll('input, select'); + for (const formInputElement of formInputElements) { + formInputElement.addEventListener('change', setUnsavedChanges); + } + function doCopy() { + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doCopyLotOccupancy`, { + lotOccupancyId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + clearUnsavedChanges(); + window.location.href = los.getLotOccupancyURL(responseJSON.lotOccupancyId, true); + } + else { + bulmaJS.alert({ + title: 'Error Copying Record', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + document + .querySelector('#button--copyLotOccupancy') + ?.addEventListener('click', (clickEvent) => { + clickEvent.preventDefault(); + if (los.hasUnsavedChanges()) { + bulmaJS.alert({ + title: 'Unsaved Changes', + message: 'Please save all unsaved changes before continuing.', + contextualColorName: 'warning' + }); + } + else { + bulmaJS.confirm({ + title: `Copy ${los.escapedAliases.Occupancy} Record as New`, + message: 'Are you sure you want to copy this record to a new record?', + contextualColorName: 'info', + okButton: { + text: 'Yes, Copy', + callbackFunction: doCopy + } + }); + } + }); + document + .querySelector('#button--deleteLotOccupancy') + ?.addEventListener('click', (clickEvent) => { + clickEvent.preventDefault(); + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancy`, { + lotOccupancyId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + clearUnsavedChanges(); + window.location.href = los.getLotOccupancyURL(); + } + else { + bulmaJS.alert({ + title: 'Error Deleting Record', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + bulmaJS.confirm({ + title: `Delete ${los.escapedAliases.Occupancy} Record`, + message: 'Are you sure you want to delete this record?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete', + callbackFunction: doDelete + } + }); + }); + document + .querySelector('#button--createWorkOrder') + ?.addEventListener('click', (clickEvent) => { + clickEvent.preventDefault(); + let createCloseModalFunction; + function doCreate(formEvent) { + formEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/workOrders/doCreateWorkOrder`, formEvent.currentTarget, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + createCloseModalFunction(); + bulmaJS.confirm({ + title: 'Work Order Created Successfully', + message: 'Would you like to open the work order now?', + contextualColorName: 'success', + okButton: { + text: 'Yes, Open the Work Order', + callbackFunction: () => { + window.location.href = los.getWorkOrderURL(responseJSON.workOrderId, true); + } + } + }); + } + else { + bulmaJS.alert({ + title: 'Error Creating Work Order', + message: responseJSON.errorMessage, + contextualColorName: 'danger' + }); + } + }); + } + cityssm.openHtmlModal('lotOccupancy-createWorkOrder', { + onshow(modalElement) { + ; + modalElement.querySelector('#workOrderCreate--lotOccupancyId').value = lotOccupancyId; + modalElement.querySelector('#workOrderCreate--workOrderOpenDateString').value = cityssm.dateToString(new Date()); + const workOrderTypeSelectElement = modalElement.querySelector('#workOrderCreate--workOrderTypeId'); + const workOrderTypes = exports + .workOrderTypes; + if (workOrderTypes.length === 1) { + workOrderTypeSelectElement.innerHTML = ''; + } + for (const workOrderType of workOrderTypes) { + const optionElement = document.createElement('option'); + optionElement.value = workOrderType.workOrderTypeId.toString(); + optionElement.textContent = workOrderType.workOrderType ?? ''; + workOrderTypeSelectElement.append(optionElement); + } + }, + onshown(modalElement, closeModalFunction) { + createCloseModalFunction = closeModalFunction; + bulmaJS.toggleHtmlClipped(); + modalElement.querySelector('#workOrderCreate--workOrderTypeId').focus(); + modalElement + .querySelector('form') + ?.addEventListener('submit', doCreate); + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + document.querySelector('#button--createWorkOrder').focus(); + } + }); + }); + // Occupancy Type + const occupancyTypeIdElement = document.querySelector('#lotOccupancy--occupancyTypeId'); + if (isCreate) { + const lotOccupancyFieldsContainerElement = document.querySelector('#container--lotOccupancyFields'); + occupancyTypeIdElement.addEventListener('change', () => { + if (occupancyTypeIdElement.value === '') { + // eslint-disable-next-line no-unsanitized/property + lotOccupancyFieldsContainerElement.innerHTML = `
    +

    Select the ${los.escapedAliases.occupancy} type to load the available fields.

    +
    `; + return; + } + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doGetOccupancyTypeFields`, { + occupancyTypeId: occupancyTypeIdElement.value + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.occupancyTypeFields.length === 0) { + // eslint-disable-next-line no-unsanitized/property + lotOccupancyFieldsContainerElement.innerHTML = `
    +

    There are no additional fields for this ${los.escapedAliases.occupancy} type.

    +
    `; + return; + } + lotOccupancyFieldsContainerElement.innerHTML = ''; + let occupancyTypeFieldIds = ''; + for (const occupancyTypeField of responseJSON.occupancyTypeFields) { + occupancyTypeFieldIds += `,${occupancyTypeField.occupancyTypeFieldId.toString()}`; + const fieldName = `lotOccupancyFieldValue_${occupancyTypeField.occupancyTypeFieldId.toString()}`; + const fieldId = `lotOccupancy--${fieldName}`; + const fieldElement = document.createElement('div'); + fieldElement.className = 'field'; + fieldElement.innerHTML = `
    `; + fieldElement.querySelector('label').textContent = occupancyTypeField.occupancyTypeField; + if ((occupancyTypeField.occupancyTypeFieldValues ?? '') === '') { + const inputElement = document.createElement('input'); + inputElement.className = 'input'; + inputElement.id = fieldId; + inputElement.name = fieldName; + inputElement.type = 'text'; + inputElement.required = occupancyTypeField.isRequired; + inputElement.minLength = + occupancyTypeField.minimumLength; + inputElement.maxLength = + occupancyTypeField.maximumLength; + if ((occupancyTypeField.pattern ?? '') !== '') { + inputElement.pattern = occupancyTypeField.pattern; + } + ; + fieldElement.querySelector('.control').append(inputElement); + } + else { + ; + fieldElement.querySelector('.control').innerHTML = `
    + +
    `; + const selectElement = fieldElement.querySelector('select'); + selectElement.required = occupancyTypeField.isRequired; + const optionValues = occupancyTypeField.occupancyTypeFieldValues.split('\n'); + for (const optionValue of optionValues) { + const optionElement = document.createElement('option'); + optionElement.value = optionValue; + optionElement.textContent = optionValue; + selectElement.append(optionElement); + } + } + console.log(fieldElement); + lotOccupancyFieldsContainerElement.append(fieldElement); + } + lotOccupancyFieldsContainerElement.insertAdjacentHTML('beforeend', + // eslint-disable-next-line no-secrets/no-secrets + ``); + }); + }); + } + else { + const originalOccupancyTypeId = occupancyTypeIdElement.value; + occupancyTypeIdElement.addEventListener('change', () => { + if (occupancyTypeIdElement.value !== originalOccupancyTypeId) { + bulmaJS.confirm({ + title: 'Confirm Change', + message: `Are you sure you want to change the ${los.escapedAliases.occupancy} type?\n + This change affects the additional fields associated with this record, and may also affect the available fees.`, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Keep the Change', + callbackFunction: () => { + refreshAfterSave = true; + } + }, + cancelButton: { + text: 'Revert the Change', + callbackFunction: () => { + occupancyTypeIdElement.value = originalOccupancyTypeId; + } + } + }); + } + }); + } + // Lot Selector + const lotNameElement = document.querySelector('#lotOccupancy--lotName'); + lotNameElement.addEventListener('click', (clickEvent) => { + const currentLotName = clickEvent.currentTarget.value; + let lotSelectCloseModalFunction; + let lotSelectModalElement; + let lotSelectFormElement; + let lotSelectResultsElement; + function renderSelectedLotAndClose(lotId, lotName) { + ; + document.querySelector('#lotOccupancy--lotId').value = lotId.toString(); + document.querySelector('#lotOccupancy--lotName').value = lotName; + setUnsavedChanges(); + lotSelectCloseModalFunction(); + } + function selectExistingLot(clickEvent) { + clickEvent.preventDefault(); + const selectedLotElement = clickEvent.currentTarget; + renderSelectedLotAndClose(selectedLotElement.dataset.lotId ?? '', selectedLotElement.dataset.lotName ?? ''); + } + function searchLots() { + // eslint-disable-next-line no-unsanitized/property + lotSelectResultsElement.innerHTML = + los.getLoadingParagraphHTML('Searching...'); + cityssm.postJSON(`${los.urlPrefix}/lots/doSearchLots`, lotSelectFormElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.count === 0) { + lotSelectResultsElement.innerHTML = `
    +

    No results.

    +
    `; + return; + } + const panelElement = document.createElement('div'); + panelElement.className = 'panel'; + for (const lot of responseJSON.lots) { + const panelBlockElement = document.createElement('a'); + panelBlockElement.className = 'panel-block is-block'; + panelBlockElement.href = '#'; + panelBlockElement.dataset.lotId = lot.lotId.toString(); + panelBlockElement.dataset.lotName = lot.lotName; + // eslint-disable-next-line no-unsanitized/property + panelBlockElement.innerHTML = `
    +
    + ${cityssm.escapeHTML(lot.lotName ?? '')}
    + ${cityssm.escapeHTML(lot.mapName ?? '')} +
    +
    + ${cityssm.escapeHTML(lot.lotStatus)}
    + + ${lot.lotOccupancyCount > 0 ? 'Currently Occupied' : ''} + +
    +
    `; + panelBlockElement.addEventListener('click', selectExistingLot); + panelElement.append(panelBlockElement); + } + lotSelectResultsElement.innerHTML = ''; + lotSelectResultsElement.append(panelElement); + }); + } + function createLotAndSelect(submitEvent) { + submitEvent.preventDefault(); + const lotName = lotSelectModalElement.querySelector('#lotCreate--lotName').value; + cityssm.postJSON(`${los.urlPrefix}/lots/doCreateLot`, submitEvent.currentTarget, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + renderSelectedLotAndClose(responseJSON.lotId ?? '', lotName); + } + else { + bulmaJS.alert({ + title: `Error Creating ${los.escapedAliases.Lot}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + cityssm.openHtmlModal('lotOccupancy-selectLot', { + onshow(modalElement) { + los.populateAliases(modalElement); + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped(); + lotSelectModalElement = modalElement; + lotSelectCloseModalFunction = closeModalFunction; + bulmaJS.init(modalElement); + // search Tab + const lotNameFilterElement = modalElement.querySelector('#lotSelect--lotName'); + if (document.querySelector('#lotOccupancy--lotId') + .value !== '') { + lotNameFilterElement.value = currentLotName; + } + lotNameFilterElement.focus(); + lotNameFilterElement.addEventListener('change', searchLots); + const occupancyStatusFilterElement = modalElement.querySelector('#lotSelect--occupancyStatus'); + occupancyStatusFilterElement.addEventListener('change', searchLots); + if (currentLotName !== '') { + occupancyStatusFilterElement.value = ''; + } + lotSelectFormElement = modalElement.querySelector('#form--lotSelect'); + lotSelectResultsElement = modalElement.querySelector('#resultsContainer--lotSelect'); + lotSelectFormElement.addEventListener('submit', (submitEvent) => { + submitEvent.preventDefault(); + }); + searchLots(); + // Create Tab + if (exports.lotNamePattern) { + const regex = exports.lotNamePattern; + modalElement.querySelector('#lotCreate--lotName').pattern = regex.source; + } + const lotTypeElement = modalElement.querySelector('#lotCreate--lotTypeId'); + for (const lotType of exports.lotTypes) { + const optionElement = document.createElement('option'); + optionElement.value = lotType.lotTypeId.toString(); + optionElement.textContent = lotType.lotType; + lotTypeElement.append(optionElement); + } + const lotStatusElement = modalElement.querySelector('#lotCreate--lotStatusId'); + for (const lotStatus of exports.lotStatuses) { + const optionElement = document.createElement('option'); + optionElement.value = lotStatus.lotStatusId.toString(); + optionElement.textContent = lotStatus.lotStatus; + lotStatusElement.append(optionElement); + } + const mapElement = modalElement.querySelector('#lotCreate--mapId'); + for (const map of exports.maps) { + const optionElement = document.createElement('option'); + optionElement.value = map.mapId.toString(); + optionElement.textContent = + (map.mapName ?? '') === '' ? '(No Name)' : map.mapName ?? ''; + mapElement.append(optionElement); + } + ; + modalElement.querySelector('#form--lotCreate').addEventListener('submit', createLotAndSelect); + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + } + }); + }); + document + .querySelector('.is-lot-view-button') + ?.addEventListener('click', () => { + const lotId = document.querySelector('#lotOccupancy--lotId').value; + if (lotId === '') { + bulmaJS.alert({ + message: `No ${los.escapedAliases.lot} selected.`, + contextualColorName: 'info' + }); + } + else { + window.open(`${los.urlPrefix}/lots/${lotId}`); + } + }); + document + .querySelector('.is-clear-lot-button') + ?.addEventListener('click', () => { + if (lotNameElement.disabled) { + bulmaJS.alert({ + message: 'You need to unlock the field before clearing it.', + contextualColorName: 'info' + }); + } + else { + lotNameElement.value = `(No ${los.escapedAliases.Lot})`; + document.querySelector('#lotOccupancy--lotId').value = ''; + setUnsavedChanges(); + } + }); + // Start Date + los.initializeDatePickers(formElement); + document + .querySelector('#lotOccupancy--occupancyStartDateString') + ?.addEventListener('change', () => { + const endDatePicker = document.querySelector('#lotOccupancy--occupancyEndDateString').bulmaCalendar.datePicker; + endDatePicker.min = document.querySelector('#lotOccupancy--occupancyStartDateString').value; + endDatePicker.refresh(); + }); + los.initializeUnlockFieldButtons(formElement); + (() => { + let lotOccupancyOccupants = exports.lotOccupancyOccupants; + delete exports.lotOccupancyOccupants; + function openEditLotOccupancyOccupant(clickEvent) { + const lotOccupantIndex = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset + .lotOccupantIndex ?? '', 10); + const lotOccupancyOccupant = lotOccupancyOccupants.find((currentLotOccupancyOccupant) => { + return (currentLotOccupancyOccupant.lotOccupantIndex === lotOccupantIndex); + }); + let editFormElement; + let editCloseModalFunction; + function editOccupant(submitEvent) { + submitEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyOccupant`, editFormElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupancyOccupants = responseJSON.lotOccupancyOccupants; + editCloseModalFunction(); + renderLotOccupancyOccupants(); + } + else { + bulmaJS.alert({ + title: `Error Updating ${los.escapedAliases.Occupant}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + cityssm.openHtmlModal('lotOccupancy-editOccupant', { + onshow(modalElement) { + los.populateAliases(modalElement); + modalElement.querySelector('#lotOccupancyOccupantEdit--lotOccupancyId').value = lotOccupancyId; + modalElement.querySelector('#lotOccupancyOccupantEdit--lotOccupantIndex').value = lotOccupantIndex.toString(); + const lotOccupantTypeSelectElement = modalElement.querySelector('#lotOccupancyOccupantEdit--lotOccupantTypeId'); + let lotOccupantTypeSelected = false; + for (const lotOccupantType of exports.lotOccupantTypes) { + const optionElement = document.createElement('option'); + optionElement.value = lotOccupantType.lotOccupantTypeId.toString(); + optionElement.textContent = lotOccupantType.lotOccupantType; + optionElement.dataset.occupantCommentTitle = + lotOccupantType.occupantCommentTitle; + optionElement.dataset.fontAwesomeIconClass = + lotOccupantType.fontAwesomeIconClass; + if (lotOccupantType.lotOccupantTypeId === + lotOccupancyOccupant.lotOccupantTypeId) { + optionElement.selected = true; + lotOccupantTypeSelected = true; + } + lotOccupantTypeSelectElement.append(optionElement); + } + if (!lotOccupantTypeSelected) { + const optionElement = document.createElement('option'); + optionElement.value = + lotOccupancyOccupant.lotOccupantTypeId?.toString() ?? ''; + optionElement.textContent = + lotOccupancyOccupant.lotOccupantType ?? ''; + optionElement.dataset.occupantCommentTitle = + lotOccupancyOccupant.occupantCommentTitle; + optionElement.dataset.fontAwesomeIconClass = + lotOccupancyOccupant.fontAwesomeIconClass; + optionElement.selected = true; + lotOccupantTypeSelectElement.append(optionElement); + } + ; + modalElement.querySelector('#lotOccupancyOccupantEdit--fontAwesomeIconClass').innerHTML = + ``; + modalElement.querySelector('#lotOccupancyOccupantEdit--occupantName').value = lotOccupancyOccupant.occupantName ?? ''; + modalElement.querySelector('#lotOccupancyOccupantEdit--occupantFamilyName').value = lotOccupancyOccupant.occupantFamilyName ?? ''; + modalElement.querySelector('#lotOccupancyOccupantEdit--occupantAddress1').value = lotOccupancyOccupant.occupantAddress1 ?? ''; + modalElement.querySelector('#lotOccupancyOccupantEdit--occupantAddress2').value = lotOccupancyOccupant.occupantAddress2 ?? ''; + modalElement.querySelector('#lotOccupancyOccupantEdit--occupantCity').value = lotOccupancyOccupant.occupantCity ?? ''; + modalElement.querySelector('#lotOccupancyOccupantEdit--occupantProvince').value = lotOccupancyOccupant.occupantProvince ?? ''; + modalElement.querySelector('#lotOccupancyOccupantEdit--occupantPostalCode').value = lotOccupancyOccupant.occupantPostalCode ?? ''; + modalElement.querySelector('#lotOccupancyOccupantEdit--occupantPhoneNumber').value = lotOccupancyOccupant.occupantPhoneNumber ?? ''; + modalElement.querySelector('#lotOccupancyOccupantEdit--occupantEmailAddress').value = lotOccupancyOccupant.occupantEmailAddress ?? ''; + modalElement.querySelector('#lotOccupancyOccupantEdit--occupantCommentTitle').textContent = + (lotOccupancyOccupant.occupantCommentTitle ?? '') === '' + ? 'Comment' + : lotOccupancyOccupant.occupantCommentTitle ?? ''; + modalElement.querySelector('#lotOccupancyOccupantEdit--occupantComment').value = lotOccupancyOccupant.occupantComment ?? ''; + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped(); + const lotOccupantTypeIdElement = modalElement.querySelector('#lotOccupancyOccupantEdit--lotOccupantTypeId'); + lotOccupantTypeIdElement.focus(); + lotOccupantTypeIdElement.addEventListener('change', () => { + const fontAwesomeIconClass = lotOccupantTypeIdElement.selectedOptions[0].dataset + .fontAwesomeIconClass ?? 'user'; + modalElement.querySelector('#lotOccupancyOccupantEdit--fontAwesomeIconClass').innerHTML = + ``; + let occupantCommentTitle = lotOccupantTypeIdElement.selectedOptions[0].dataset + .occupantCommentTitle ?? ''; + if (occupantCommentTitle === '') { + occupantCommentTitle = 'Comment'; + } + ; + modalElement.querySelector('#lotOccupancyOccupantEdit--occupantCommentTitle').textContent = occupantCommentTitle; + }); + editFormElement = modalElement.querySelector('form'); + editFormElement.addEventListener('submit', editOccupant); + editCloseModalFunction = closeModalFunction; + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + } + }); + } + function deleteLotOccupancyOccupant(clickEvent) { + const lotOccupantIndex = clickEvent.currentTarget.closest('tr')?.dataset.lotOccupantIndex; + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyOccupant`, { + lotOccupancyId, + lotOccupantIndex + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupancyOccupants = responseJSON.lotOccupancyOccupants; + renderLotOccupancyOccupants(); + } + else { + bulmaJS.alert({ + title: `Error Removing ${los.escapedAliases.Occupant}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + bulmaJS.confirm({ + title: `Remove ${los.escapedAliases.Occupant}?`, + message: `Are you sure you want to remove this ${los.escapedAliases.occupant}?`, + okButton: { + text: `Yes, Remove ${los.escapedAliases.Occupant}`, + callbackFunction: doDelete + }, + contextualColorName: 'warning' + }); + } + function renderLotOccupancyOccupants() { + const occupantsContainer = document.querySelector('#container--lotOccupancyOccupants'); + cityssm.clearElement(occupantsContainer); + if (lotOccupancyOccupants.length === 0) { + // eslint-disable-next-line no-unsanitized/property + occupantsContainer.innerHTML = `
    +

    There are no ${los.escapedAliases.occupants} associated with this record.

    +
    `; + return; + } + const tableElement = document.createElement('table'); + tableElement.className = 'table is-fullwidth is-striped is-hoverable'; + // eslint-disable-next-line no-unsanitized/property + tableElement.innerHTML = ` + ${los.escapedAliases.Occupant} + Address + Other Contact + Comment + Options + + `; + for (const lotOccupancyOccupant of lotOccupancyOccupants) { + const tableRowElement = document.createElement('tr'); + tableRowElement.dataset.lotOccupantIndex = + lotOccupancyOccupant.lotOccupantIndex?.toString(); + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` + ${cityssm.escapeHTML((lotOccupancyOccupant.occupantName ?? '') === '' && + (lotOccupancyOccupant.occupantFamilyName ?? '') === '' + ? '(No Name)' + : `${lotOccupancyOccupant.occupantName} ${lotOccupancyOccupant.occupantFamilyName}`)}
    + + + ${cityssm.escapeHTML(lotOccupancyOccupant.lotOccupantType ?? '')} + + + ${(lotOccupancyOccupant.occupantAddress1 ?? '') === '' + ? '' + : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress1 ?? '')}
    `} + ${(lotOccupancyOccupant.occupantAddress2 ?? '') === '' + ? '' + : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress2 ?? '')}
    `} + ${(lotOccupancyOccupant.occupantCity ?? '') === '' + ? '' + : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantCity ?? '')}, `} + ${cityssm.escapeHTML(lotOccupancyOccupant.occupantProvince ?? '')}
    + ${cityssm.escapeHTML(lotOccupancyOccupant.occupantPostalCode ?? '')} + + ${(lotOccupancyOccupant.occupantPhoneNumber ?? '') === '' + ? '' + : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantPhoneNumber ?? '')}
    `} + ${(lotOccupancyOccupant.occupantEmailAddress ?? '') === '' + ? '' + : cityssm.escapeHTML(lotOccupancyOccupant.occupantEmailAddress ?? '')} + + + ${cityssm.escapeHTML(lotOccupancyOccupant.occupantComment ?? '')} + + +
    + + +
    + `; + tableRowElement + .querySelector('.button--edit') + ?.addEventListener('click', openEditLotOccupancyOccupant); + tableRowElement + .querySelector('.button--delete') + ?.addEventListener('click', deleteLotOccupancyOccupant); + tableElement.querySelector('tbody')?.append(tableRowElement); + } + occupantsContainer.append(tableElement); + } + if (isCreate) { + const lotOccupantTypeIdElement = document.querySelector('#lotOccupancy--lotOccupantTypeId'); + lotOccupantTypeIdElement.addEventListener('change', () => { + const occupantFields = formElement.querySelectorAll("[data-table='LotOccupancyOccupant']"); + for (const occupantField of occupantFields) { + occupantField.disabled = lotOccupantTypeIdElement.value === ''; + } + let occupantCommentTitle = lotOccupantTypeIdElement.selectedOptions[0].dataset + .occupantCommentTitle ?? ''; + if (occupantCommentTitle === '') { + occupantCommentTitle = 'Comment'; + } + ; + formElement.querySelector('#lotOccupancy--occupantCommentTitle').textContent = occupantCommentTitle; + }); + } + else { + renderLotOccupancyOccupants(); + } + document + .querySelector('#button--addOccupant') + ?.addEventListener('click', () => { + let addCloseModalFunction; + let addFormElement; + let searchFormElement; + let searchResultsElement; + function addOccupant(formOrObject) { + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyOccupant`, formOrObject, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupancyOccupants = responseJSON.lotOccupancyOccupants; + addCloseModalFunction(); + renderLotOccupancyOccupants(); + } + else { + bulmaJS.alert({ + title: `Error Adding ${los.escapedAliases.Occupant}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + function addOccupantFromForm(submitEvent) { + submitEvent.preventDefault(); + addOccupant(addFormElement); + } + let pastOccupantSearchResults = []; + function addOccupantFromCopy(clickEvent) { + clickEvent.preventDefault(); + const panelBlockElement = clickEvent.currentTarget; + const occupant = pastOccupantSearchResults[Number.parseInt(panelBlockElement.dataset.index ?? '', 10)]; + const lotOccupantTypeId = (panelBlockElement + .closest('.modal') + ?.querySelector('#lotOccupancyOccupantCopy--lotOccupantTypeId')).value; + if (lotOccupantTypeId === '') { + bulmaJS.alert({ + title: `No ${los.escapedAliases.Occupant} Type Selected`, + message: `Select a type to apply to the newly added ${los.escapedAliases.occupant}.`, + contextualColorName: 'warning' + }); + } + else { + occupant.lotOccupantTypeId = Number.parseInt(lotOccupantTypeId, 10); + occupant.lotOccupancyId = Number.parseInt(lotOccupancyId, 10); + addOccupant(occupant); + } + } + function searchOccupants(event) { + event.preventDefault(); + if (searchFormElement.querySelector('#lotOccupancyOccupantCopy--searchFilter').value === '') { + searchResultsElement.innerHTML = `
    +

    Enter a partial name or address in the search field above.

    +
    `; + return; + } + // eslint-disable-next-line no-unsanitized/property + searchResultsElement.innerHTML = + los.getLoadingParagraphHTML('Searching...'); + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doSearchPastOccupants`, searchFormElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + pastOccupantSearchResults = responseJSON.occupants; + const panelElement = document.createElement('div'); + panelElement.className = 'panel'; + for (const [index, occupant] of pastOccupantSearchResults.entries()) { + const panelBlockElement = document.createElement('a'); + panelBlockElement.className = 'panel-block is-block'; + panelBlockElement.href = '#'; + panelBlockElement.dataset.index = index.toString(); + // eslint-disable-next-line no-unsanitized/property + panelBlockElement.innerHTML = ` + ${cityssm.escapeHTML(occupant.occupantName ?? '')} ${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')} +
    +
    +
    + ${cityssm.escapeHTML(occupant.occupantAddress1 ?? '')}
    + ${(occupant.occupantAddress2 ?? '') === '' + ? '' + : `${cityssm.escapeHTML(occupant.occupantAddress2 ?? '')}
    `}${cityssm.escapeHTML(occupant.occupantCity ?? '')}, ${cityssm.escapeHTML(occupant.occupantProvince ?? '')}
    + ${cityssm.escapeHTML(occupant.occupantPostalCode ?? '')} +
    +
    + ${(occupant.occupantPhoneNumber ?? '') === '' + ? '' + : `${cityssm.escapeHTML(occupant.occupantPhoneNumber ?? '')}
    `} + ${cityssm.escapeHTML(occupant.occupantEmailAddress ?? '')}
    +
    +
    `; + panelBlockElement.addEventListener('click', addOccupantFromCopy); + panelElement.append(panelBlockElement); + } + searchResultsElement.innerHTML = ''; + searchResultsElement.append(panelElement); + }); + } + cityssm.openHtmlModal('lotOccupancy-addOccupant', { + onshow(modalElement) { + los.populateAliases(modalElement); + modalElement.querySelector('#lotOccupancyOccupantAdd--lotOccupancyId').value = lotOccupancyId; + const lotOccupantTypeSelectElement = modalElement.querySelector('#lotOccupancyOccupantAdd--lotOccupantTypeId'); + const lotOccupantTypeCopySelectElement = modalElement.querySelector('#lotOccupancyOccupantCopy--lotOccupantTypeId'); + for (const lotOccupantType of exports.lotOccupantTypes) { + const optionElement = document.createElement('option'); + optionElement.value = lotOccupantType.lotOccupantTypeId.toString(); + optionElement.textContent = lotOccupantType.lotOccupantType; + optionElement.dataset.occupantCommentTitle = + lotOccupantType.occupantCommentTitle; + optionElement.dataset.fontAwesomeIconClass = + lotOccupantType.fontAwesomeIconClass; + lotOccupantTypeSelectElement.append(optionElement); + lotOccupantTypeCopySelectElement.append(optionElement.cloneNode(true)); + } + ; + modalElement.querySelector('#lotOccupancyOccupantAdd--occupantCity').value = exports.occupantCityDefault; + modalElement.querySelector('#lotOccupancyOccupantAdd--occupantProvince').value = exports.occupantProvinceDefault; + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped(); + bulmaJS.init(modalElement); + const lotOccupantTypeIdElement = modalElement.querySelector('#lotOccupancyOccupantAdd--lotOccupantTypeId'); + lotOccupantTypeIdElement.focus(); + lotOccupantTypeIdElement.addEventListener('change', () => { + const fontAwesomeIconClass = lotOccupantTypeIdElement.selectedOptions[0].dataset + .fontAwesomeIconClass ?? 'user'; + modalElement.querySelector('#lotOccupancyOccupantAdd--fontAwesomeIconClass').innerHTML = + ``; + let occupantCommentTitle = lotOccupantTypeIdElement.selectedOptions[0].dataset + .occupantCommentTitle ?? ''; + if (occupantCommentTitle === '') { + occupantCommentTitle = 'Comment'; + } + ; + modalElement.querySelector('#lotOccupancyOccupantAdd--occupantCommentTitle').textContent = occupantCommentTitle; + }); + addFormElement = modalElement.querySelector('#form--lotOccupancyOccupantAdd'); + addFormElement.addEventListener('submit', addOccupantFromForm); + searchResultsElement = modalElement.querySelector('#lotOccupancyOccupantCopy--searchResults'); + searchFormElement = modalElement.querySelector('#form--lotOccupancyOccupantCopy'); + searchFormElement.addEventListener('submit', (formEvent) => { + formEvent.preventDefault(); + }); + modalElement.querySelector('#lotOccupancyOccupantCopy--searchFilter').addEventListener('change', searchOccupants); + addCloseModalFunction = closeModalFunction; + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + document.querySelector('#button--addOccupant').focus(); + } + }); + }); + })(); + if (!isCreate) { + /** + * Comments + */ + ; + (() => { + let lotOccupancyComments = exports.lotOccupancyComments; + delete exports.lotOccupancyComments; + function openEditLotOccupancyComment(clickEvent) { + const lotOccupancyCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset + .lotOccupancyCommentId ?? '', 10); + const lotOccupancyComment = lotOccupancyComments.find((currentLotOccupancyComment) => { + return (currentLotOccupancyComment.lotOccupancyCommentId === + lotOccupancyCommentId); + }); + let editFormElement; + let editCloseModalFunction; + function editComment(submitEvent) { + submitEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyComment`, editFormElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupancyComments = responseJSON.lotOccupancyComments ?? []; + editCloseModalFunction(); + renderLotOccupancyComments(); + } + else { + bulmaJS.alert({ + title: 'Error Updating Comment', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + cityssm.openHtmlModal('lotOccupancy-editComment', { + onshow(modalElement) { + los.populateAliases(modalElement); + modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyId').value = lotOccupancyId; + modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyCommentId').value = lotOccupancyCommentId.toString(); + modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyComment').value = lotOccupancyComment.lotOccupancyComment ?? ''; + const lotOccupancyCommentDateStringElement = modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyCommentDateString'); + lotOccupancyCommentDateStringElement.value = + lotOccupancyComment.lotOccupancyCommentDateString ?? ''; + const currentDateString = cityssm.dateToString(new Date()); + lotOccupancyCommentDateStringElement.max = + lotOccupancyComment.lotOccupancyCommentDateString <= + currentDateString + ? currentDateString + : lotOccupancyComment.lotOccupancyCommentDateString ?? ''; + modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyCommentTimeString').value = lotOccupancyComment.lotOccupancyCommentTimeString ?? ''; + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped(); + los.initializeDatePickers(modalElement); + modalElement.querySelector('#lotOccupancyCommentEdit--lotOccupancyComment').focus(); + editFormElement = modalElement.querySelector('form'); + editFormElement.addEventListener('submit', editComment); + editCloseModalFunction = closeModalFunction; + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + } + }); + } + function deleteLotOccupancyComment(clickEvent) { + const lotOccupancyCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset + .lotOccupancyCommentId ?? '', 10); + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyComment`, { + lotOccupancyId, + lotOccupancyCommentId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupancyComments = responseJSON.lotOccupancyComments; + renderLotOccupancyComments(); + } + else { + bulmaJS.alert({ + title: 'Error Removing Comment', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + bulmaJS.confirm({ + title: 'Remove Comment?', + message: 'Are you sure you want to remove this comment?', + okButton: { + text: 'Yes, Remove Comment', + callbackFunction: doDelete + }, + contextualColorName: 'warning' + }); + } + function renderLotOccupancyComments() { + const containerElement = document.querySelector('#container--lotOccupancyComments'); + if (lotOccupancyComments.length === 0) { + containerElement.innerHTML = `
    +

    There are no comments associated with this record.

    +
    `; + return; + } + const tableElement = document.createElement('table'); + tableElement.className = 'table is-fullwidth is-striped is-hoverable'; + tableElement.innerHTML = ` + Commentor + Comment Date + Comment + Options + + `; + for (const lotOccupancyComment of lotOccupancyComments) { + const tableRowElement = document.createElement('tr'); + tableRowElement.dataset.lotOccupancyCommentId = + lotOccupancyComment.lotOccupancyCommentId?.toString(); + tableRowElement.innerHTML = `${cityssm.escapeHTML(lotOccupancyComment.recordCreate_userName ?? '')} + + ${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyCommentDateString ?? '')} + ${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyCommentTime === 0 + ? '' + : lotOccupancyComment.lotOccupancyCommentTimePeriodString ?? '')} + + ${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyComment ?? '')} + +
    + + +
    + `; + tableRowElement + .querySelector('.button--edit') + ?.addEventListener('click', openEditLotOccupancyComment); + tableRowElement + .querySelector('.button--delete') + ?.addEventListener('click', deleteLotOccupancyComment); + tableElement.querySelector('tbody')?.append(tableRowElement); + } + containerElement.innerHTML = ''; + containerElement.append(tableElement); + } + document + .querySelector('#button--addComment') + ?.addEventListener('click', () => { + let addFormElement; + let addCloseModalFunction; + function addComment(submitEvent) { + submitEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyComment`, addFormElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupancyComments = responseJSON.lotOccupancyComments; + addCloseModalFunction(); + renderLotOccupancyComments(); + } + else { + bulmaJS.alert({ + title: 'Error Adding Comment', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + cityssm.openHtmlModal('lotOccupancy-addComment', { + onshow(modalElement) { + los.populateAliases(modalElement); + modalElement.querySelector('#lotOccupancyCommentAdd--lotOccupancyId').value = lotOccupancyId; + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped(); + modalElement.querySelector('#lotOccupancyCommentAdd--lotOccupancyComment').focus(); + addFormElement = modalElement.querySelector('form'); + addFormElement.addEventListener('submit', addComment); + addCloseModalFunction = closeModalFunction; + }, + onremoved: () => { + bulmaJS.toggleHtmlClipped(); + document.querySelector('#button--addComment').focus(); + } + }); + }); + renderLotOccupancyComments(); + })(); + (() => { + let lotOccupancyFees = exports.lotOccupancyFees; + delete exports.lotOccupancyFees; + const lotOccupancyFeesContainerElement = document.querySelector('#container--lotOccupancyFees'); + function getFeeGrandTotal() { + let feeGrandTotal = 0; + for (const lotOccupancyFee of lotOccupancyFees) { + feeGrandTotal += + ((lotOccupancyFee.feeAmount ?? 0) + + (lotOccupancyFee.taxAmount ?? 0)) * + (lotOccupancyFee.quantity ?? 0); + } + return feeGrandTotal; + } + function editLotOccupancyFeeQuantity(clickEvent) { + const feeId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset + .feeId ?? '', 10); + const fee = lotOccupancyFees.find((possibleFee) => { + return possibleFee.feeId === feeId; + }); + let updateCloseModalFunction; + function doUpdateQuantity(formEvent) { + formEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyFeeQuantity`, formEvent.currentTarget, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupancyFees = responseJSON.lotOccupancyFees; + renderLotOccupancyFees(); + updateCloseModalFunction(); + } + else { + bulmaJS.alert({ + title: 'Error Updating Quantity', + message: 'Please try again.', + contextualColorName: 'danger' + }); + } + }); + } + cityssm.openHtmlModal('lotOccupancy-editFeeQuantity', { + onshow(modalElement) { + ; + modalElement.querySelector('#lotOccupancyFeeQuantity--lotOccupancyId').value = lotOccupancyId; + modalElement.querySelector('#lotOccupancyFeeQuantity--feeId').value = fee.feeId.toString(); + modalElement.querySelector('#lotOccupancyFeeQuantity--quantity').valueAsNumber = fee.quantity ?? 0; + modalElement.querySelector('#lotOccupancyFeeQuantity--quantityUnit').textContent = fee.quantityUnit ?? ''; + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped(); + updateCloseModalFunction = closeModalFunction; + modalElement.querySelector('#lotOccupancyFeeQuantity--quantity').focus(); + modalElement + .querySelector('form') + ?.addEventListener('submit', doUpdateQuantity); + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + } + }); + } + function deleteLotOccupancyFee(clickEvent) { + const feeId = clickEvent.currentTarget.closest('.container--lotOccupancyFee').dataset.feeId; + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyFee`, { + lotOccupancyId, + feeId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupancyFees = responseJSON.lotOccupancyFees; + renderLotOccupancyFees(); + } + else { + bulmaJS.alert({ + title: 'Error Deleting Fee', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + bulmaJS.confirm({ + title: 'Delete Fee', + message: 'Are you sure you want to delete this fee?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Fee', + callbackFunction: doDelete + } + }); + } + function renderLotOccupancyFees() { + if (lotOccupancyFees.length === 0) { + lotOccupancyFeesContainerElement.innerHTML = `
    +

    There are no fees associated with this record.

    +
    `; + renderLotOccupancyTransactions(); + return; + } + // eslint-disable-next-line no-secrets/no-secrets + lotOccupancyFeesContainerElement.innerHTML = ` + + + + + + + + + + + + + + + + + + + + + + +
    FeeUnit Cost×QuantityequalsTotalOptions
    Subtotal
    Tax
    Grand Total
    `; + let feeAmountTotal = 0; + let taxAmountTotal = 0; + for (const lotOccupancyFee of lotOccupancyFees) { + const tableRowElement = document.createElement('tr'); + tableRowElement.className = 'container--lotOccupancyFee'; + tableRowElement.dataset.feeId = lotOccupancyFee.feeId.toString(); + tableRowElement.dataset.includeQuantity = + lotOccupancyFee.includeQuantity ?? false ? '1' : '0'; + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` + ${cityssm.escapeHTML(lotOccupancyFee.feeName ?? '')}
    + ${cityssm.escapeHTML(lotOccupancyFee.feeCategory ?? '')} + + ${lotOccupancyFee.quantity === 1 + ? '' + : ` + $${lotOccupancyFee.feeAmount?.toFixed(2)} + + × + ${lotOccupancyFee.quantity?.toString()} + =`} + + $${((lotOccupancyFee.feeAmount ?? 0) * (lotOccupancyFee.quantity ?? 0)).toFixed(2)} + + +
    + ${lotOccupancyFee.includeQuantity ?? false + ? `` + : ''} + +
    + `; + tableRowElement + .querySelector('.button--editQuantity') + ?.addEventListener('click', editLotOccupancyFeeQuantity); + tableRowElement + .querySelector('.button--delete') + ?.addEventListener('click', deleteLotOccupancyFee); + lotOccupancyFeesContainerElement + .querySelector('tbody') + ?.append(tableRowElement); + feeAmountTotal += + (lotOccupancyFee.feeAmount ?? 0) * (lotOccupancyFee.quantity ?? 0); + taxAmountTotal += + (lotOccupancyFee.taxAmount ?? 0) * (lotOccupancyFee.quantity ?? 0); + } + ; + lotOccupancyFeesContainerElement.querySelector('#lotOccupancyFees--feeAmountTotal').textContent = `$${feeAmountTotal.toFixed(2)}`; + lotOccupancyFeesContainerElement.querySelector('#lotOccupancyFees--taxAmountTotal').textContent = `$${taxAmountTotal.toFixed(2)}`; + lotOccupancyFeesContainerElement.querySelector('#lotOccupancyFees--grandTotal').textContent = `$${(feeAmountTotal + taxAmountTotal).toFixed(2)}`; + renderLotOccupancyTransactions(); + } + const addFeeButtonElement = document.querySelector('#button--addFee'); + addFeeButtonElement.addEventListener('click', () => { + if (los.hasUnsavedChanges()) { + bulmaJS.alert({ + message: 'Please save all unsaved changes before adding fees.', + contextualColorName: 'warning' + }); + return; + } + let feeCategories; + let feeFilterElement; + let feeFilterResultsElement; + function doAddFeeCategory(clickEvent) { + clickEvent.preventDefault(); + const feeCategoryId = Number.parseInt(clickEvent.currentTarget.dataset.feeCategoryId ?? + '', 10); + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyFeeCategory`, { + lotOccupancyId, + feeCategoryId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupancyFees = responseJSON.lotOccupancyFees; + renderLotOccupancyFees(); + bulmaJS.alert({ + message: 'Fee Group Added Successfully', + contextualColorName: 'success' + }); + } + else { + bulmaJS.alert({ + title: 'Error Adding Fee', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + function doAddFee(feeId, quantity = 1) { + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyFee`, { + lotOccupancyId, + feeId, + quantity + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupancyFees = responseJSON.lotOccupancyFees; + renderLotOccupancyFees(); + filterFees(); + } + else { + bulmaJS.alert({ + title: 'Error Adding Fee', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + function doSetQuantityAndAddFee(fee) { + let quantityElement; + let quantityCloseModalFunction; + function doSetQuantity(submitEvent) { + submitEvent.preventDefault(); + doAddFee(fee.feeId, quantityElement.value); + quantityCloseModalFunction(); + } + cityssm.openHtmlModal('lotOccupancy-setFeeQuantity', { + onshow(modalElement) { + ; + modalElement.querySelector('#lotOccupancyFeeQuantity--quantityUnit').textContent = fee.quantityUnit ?? ''; + }, + onshown(modalElement, closeModalFunction) { + quantityCloseModalFunction = closeModalFunction; + quantityElement = modalElement.querySelector('#lotOccupancyFeeQuantity--quantity'); + modalElement + .querySelector('form') + ?.addEventListener('submit', doSetQuantity); + } + }); + } + function tryAddFee(clickEvent) { + clickEvent.preventDefault(); + const feeId = Number.parseInt(clickEvent.currentTarget.dataset.feeId ?? '', 10); + const feeCategoryId = Number.parseInt(clickEvent.currentTarget.dataset.feeCategoryId ?? + '', 10); + const feeCategory = feeCategories.find((currentFeeCategory) => { + return currentFeeCategory.feeCategoryId === feeCategoryId; + }); + const fee = feeCategory.fees.find((currentFee) => { + return currentFee.feeId === feeId; + }); + if (fee.includeQuantity ?? false) { + doSetQuantityAndAddFee(fee); + } + else { + doAddFee(feeId); + } + } + function filterFees() { + const filterStringPieces = feeFilterElement.value + .trim() + .toLowerCase() + .split(' '); + feeFilterResultsElement.innerHTML = ''; + for (const feeCategory of feeCategories) { + const categoryContainerElement = document.createElement('div'); + categoryContainerElement.className = 'container--feeCategory'; + categoryContainerElement.dataset.feeCategoryId = + feeCategory.feeCategoryId.toString(); + categoryContainerElement.innerHTML = `
    +
    +

    + ${cityssm.escapeHTML(feeCategory.feeCategory ?? '')} +

    +
    +
    +
    `; + if (feeCategory.isGroupedFee) { + // eslint-disable-next-line no-unsanitized/method + categoryContainerElement + .querySelector('.columns') + ?.insertAdjacentHTML('beforeend', `
    + +
    `); + categoryContainerElement + .querySelector('button') + ?.addEventListener('click', doAddFeeCategory); + } + let hasFees = false; + for (const fee of feeCategory.fees) { + // Don't include already applied fees that limit quantity + if (lotOccupancyFeesContainerElement.querySelector(`.container--lotOccupancyFee[data-fee-id='${fee.feeId}'][data-include-quantity='0']`) !== null) { + continue; + } + let includeFee = true; + const feeSearchString = `${feeCategory.feeCategory ?? ''} ${fee.feeName ?? ''} ${fee.feeDescription ?? ''}`.toLowerCase(); + for (const filterStringPiece of filterStringPieces) { + if (!feeSearchString.includes(filterStringPiece)) { + includeFee = false; + break; + } + } + if (!includeFee) { + continue; + } + hasFees = true; + const panelBlockElement = document.createElement(feeCategory.isGroupedFee ? 'div' : 'a'); + panelBlockElement.className = + 'panel-block is-block container--fee'; + panelBlockElement.dataset.feeId = fee.feeId.toString(); + panelBlockElement.dataset.feeCategoryId = + feeCategory.feeCategoryId.toString(); + // eslint-disable-next-line no-unsanitized/property + panelBlockElement.innerHTML = `${cityssm.escapeHTML(fee.feeName ?? '')}
    + + ${ + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + cityssm + .escapeHTML(fee.feeDescription ?? '') + .replaceAll('\n', '
    ')} +
    `; + if (!feeCategory.isGroupedFee) { + ; + panelBlockElement.href = '#'; + panelBlockElement.addEventListener('click', tryAddFee); + } + ; + categoryContainerElement.querySelector('.panel').append(panelBlockElement); + } + if (hasFees) { + feeFilterResultsElement.append(categoryContainerElement); + } + } + } + cityssm.openHtmlModal('lotOccupancy-addFee', { + onshow(modalElement) { + feeFilterElement = modalElement.querySelector('#feeSelect--feeName'); + feeFilterResultsElement = modalElement.querySelector('#resultsContainer--feeSelect'); + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doGetFees`, { + lotOccupancyId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + feeCategories = responseJSON.feeCategories; + feeFilterElement.disabled = false; + feeFilterElement.addEventListener('keyup', filterFees); + feeFilterElement.focus(); + filterFees(); + }); + }, + onshown() { + bulmaJS.toggleHtmlClipped(); + }, + onhidden() { + renderLotOccupancyFees(); + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + addFeeButtonElement.focus(); + } + }); + }); + let lotOccupancyTransactions = exports.lotOccupancyTransactions; + delete exports.lotOccupancyTransactions; + const lotOccupancyTransactionsContainerElement = document.querySelector('#container--lotOccupancyTransactions'); + function getTransactionGrandTotal() { + let transactionGrandTotal = 0; + for (const lotOccupancyTransaction of lotOccupancyTransactions) { + transactionGrandTotal += lotOccupancyTransaction.transactionAmount; + } + return transactionGrandTotal; + } + function editLotOccupancyTransaction(clickEvent) { + const transactionIndex = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset + .transactionIndex ?? '', 10); + const transaction = lotOccupancyTransactions.find((possibleTransaction) => { + return possibleTransaction.transactionIndex === transactionIndex; + }); + let editCloseModalFunction; + function doEdit(formEvent) { + formEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyTransaction`, formEvent.currentTarget, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupancyTransactions = responseJSON.lotOccupancyTransactions; + renderLotOccupancyTransactions(); + editCloseModalFunction(); + } + else { + bulmaJS.alert({ + title: 'Error Updating Transaction', + message: 'Please try again.', + contextualColorName: 'danger' + }); + } + }); + } + cityssm.openHtmlModal('lotOccupancy-editTransaction', { + onshow(modalElement) { + los.populateAliases(modalElement); + modalElement.querySelector('#lotOccupancyTransactionEdit--lotOccupancyId').value = lotOccupancyId; + modalElement.querySelector('#lotOccupancyTransactionEdit--transactionIndex').value = transaction.transactionIndex?.toString() ?? ''; + modalElement.querySelector('#lotOccupancyTransactionEdit--transactionAmount').value = transaction.transactionAmount.toFixed(2); + modalElement.querySelector('#lotOccupancyTransactionEdit--externalReceiptNumber').value = transaction.externalReceiptNumber ?? ''; + modalElement.querySelector('#lotOccupancyTransactionEdit--transactionNote').value = transaction.transactionNote ?? ''; + modalElement.querySelector('#lotOccupancyTransactionEdit--transactionDateString').value = transaction.transactionDateString ?? ''; + modalElement.querySelector('#lotOccupancyTransactionEdit--transactionTimeString').value = transaction.transactionTimeString ?? ''; + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped(); + los.initializeDatePickers(modalElement); + modalElement.querySelector('#lotOccupancyTransactionEdit--transactionAmount').focus(); + modalElement + .querySelector('form') + ?.addEventListener('submit', doEdit); + editCloseModalFunction = closeModalFunction; + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + } + }); + } + function deleteLotOccupancyTransaction(clickEvent) { + const transactionIndex = clickEvent.currentTarget.closest('.container--lotOccupancyTransaction').dataset.transactionIndex; + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyTransaction`, { + lotOccupancyId, + transactionIndex + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupancyTransactions = responseJSON.lotOccupancyTransactions; + renderLotOccupancyTransactions(); + } + else { + bulmaJS.alert({ + title: 'Error Deleting Transaction', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + bulmaJS.confirm({ + title: 'Delete Trasnaction', + message: 'Are you sure you want to delete this transaction?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Transaction', + callbackFunction: doDelete + } + }); + } + function renderLotOccupancyTransactions() { + if (lotOccupancyTransactions.length === 0) { + // eslint-disable-next-line no-unsanitized/property + lotOccupancyTransactionsContainerElement.innerHTML = `
    +

    There are no transactions associated with this record.

    +
    `; + return; + } + // eslint-disable-next-line no-unsanitized/property + lotOccupancyTransactionsContainerElement.innerHTML = ` + + + + + + + + + + + + +
    Date${los.escapedAliases.ExternalReceiptNumber}AmountOptions
    Transaction Total
    `; + let transactionGrandTotal = 0; + for (const lotOccupancyTransaction of lotOccupancyTransactions) { + transactionGrandTotal += lotOccupancyTransaction.transactionAmount; + const tableRowElement = document.createElement('tr'); + tableRowElement.className = 'container--lotOccupancyTransaction'; + tableRowElement.dataset.transactionIndex = + lotOccupancyTransaction.transactionIndex?.toString(); + let externalReceiptNumberHTML = ''; + if (lotOccupancyTransaction.externalReceiptNumber !== '') { + externalReceiptNumberHTML = cityssm.escapeHTML(lotOccupancyTransaction.externalReceiptNumber ?? ''); + if (los.dynamicsGPIntegrationIsEnabled) { + if (lotOccupancyTransaction.dynamicsGPDocument === undefined) { + externalReceiptNumberHTML += ` + + `; + } + else if (lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(2) === lotOccupancyTransaction.transactionAmount.toFixed(2)) { + externalReceiptNumberHTML += ` + + `; + } + else { + externalReceiptNumberHTML += ` + + `; + } + } + externalReceiptNumberHTML += '
    '; + } + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` + ${cityssm.escapeHTML(lotOccupancyTransaction.transactionDateString ?? '')} + + + ${externalReceiptNumberHTML} + ${cityssm.escapeHTML(lotOccupancyTransaction.transactionNote ?? '')} + + + $${cityssm.escapeHTML(lotOccupancyTransaction.transactionAmount.toFixed(2))} + + +
    + + +
    + `; + tableRowElement + .querySelector('.button--edit') + ?.addEventListener('click', editLotOccupancyTransaction); + tableRowElement + .querySelector('.button--delete') + ?.addEventListener('click', deleteLotOccupancyTransaction); + lotOccupancyTransactionsContainerElement + .querySelector('tbody') + ?.append(tableRowElement); + } + ; + lotOccupancyTransactionsContainerElement.querySelector('#lotOccupancyTransactions--grandTotal').textContent = `$${transactionGrandTotal.toFixed(2)}`; + const feeGrandTotal = getFeeGrandTotal(); + if (feeGrandTotal.toFixed(2) !== transactionGrandTotal.toFixed(2)) { + lotOccupancyTransactionsContainerElement.insertAdjacentHTML('afterbegin', `
    +
    +
    +
    +
    Outstanding Balance
    +
    +
    +
    + $${cityssm.escapeHTML((feeGrandTotal - transactionGrandTotal).toFixed(2))} +
    +
    +
    +
    `); + } + } + const addTransactionButtonElement = document.querySelector('#button--addTransaction'); + addTransactionButtonElement.addEventListener('click', () => { + let transactionAmountElement; + let externalReceiptNumberElement; + let addCloseModalFunction; + function doAddTransaction(submitEvent) { + submitEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doAddLotOccupancyTransaction`, submitEvent.currentTarget, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + lotOccupancyTransactions = responseJSON.lotOccupancyTransactions; + addCloseModalFunction(); + renderLotOccupancyTransactions(); + } + else { + bulmaJS.confirm({ + title: 'Error Adding Transaction', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + // eslint-disable-next-line @typescript-eslint/naming-convention + function dynamicsGP_refreshExternalReceiptNumberIcon() { + const externalReceiptNumber = externalReceiptNumberElement.value; + const iconElement = externalReceiptNumberElement + .closest('.control') + ?.querySelector('.icon'); + const helpTextElement = externalReceiptNumberElement + .closest('.field') + ?.querySelector('.help'); + if (externalReceiptNumber === '') { + helpTextElement.innerHTML = ' '; + iconElement.innerHTML = + ''; + return; + } + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doGetDynamicsGPDocument`, { + externalReceiptNumber + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (!responseJSON.success || + responseJSON.dynamicsGPDocument === undefined) { + helpTextElement.textContent = 'No Matching Document Found'; + iconElement.innerHTML = + ''; + } + else if (transactionAmountElement.valueAsNumber === + responseJSON.dynamicsGPDocument.documentTotal) { + helpTextElement.textContent = 'Matching Document Found'; + iconElement.innerHTML = + ''; + } + else { + helpTextElement.textContent = `Matching Document: $${responseJSON.dynamicsGPDocument.documentTotal.toFixed(2)}`; + iconElement.innerHTML = + ''; + } + }); + } + cityssm.openHtmlModal('lotOccupancy-addTransaction', { + onshow(modalElement) { + los.populateAliases(modalElement); + modalElement.querySelector('#lotOccupancyTransactionAdd--lotOccupancyId').value = lotOccupancyId.toString(); + const feeGrandTotal = getFeeGrandTotal(); + const transactionGrandTotal = getTransactionGrandTotal(); + transactionAmountElement = modalElement.querySelector('#lotOccupancyTransactionAdd--transactionAmount'); + transactionAmountElement.min = (-1 * transactionGrandTotal).toFixed(2); + transactionAmountElement.max = Math.max(feeGrandTotal - transactionGrandTotal, 0).toFixed(2); + transactionAmountElement.value = Math.max(feeGrandTotal - transactionGrandTotal, 0).toFixed(2); + if (los.dynamicsGPIntegrationIsEnabled) { + externalReceiptNumberElement = modalElement.querySelector( + // eslint-disable-next-line no-secrets/no-secrets + '#lotOccupancyTransactionAdd--externalReceiptNumber'); + const externalReceiptNumberControlElement = externalReceiptNumberElement.closest('.control'); + externalReceiptNumberControlElement.classList.add('has-icons-right'); + externalReceiptNumberControlElement.insertAdjacentHTML('beforeend', ''); + externalReceiptNumberControlElement.insertAdjacentHTML('afterend', '

    '); + externalReceiptNumberElement.addEventListener('change', dynamicsGP_refreshExternalReceiptNumberIcon); + transactionAmountElement.addEventListener('change', dynamicsGP_refreshExternalReceiptNumberIcon); + dynamicsGP_refreshExternalReceiptNumberIcon(); + } + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped(); + transactionAmountElement.focus(); + addCloseModalFunction = closeModalFunction; + modalElement + .querySelector('form') + ?.addEventListener('submit', doAddTransaction); + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + addTransactionButtonElement.focus(); + } + }); + }); + renderLotOccupancyFees(); + })(); + } +})(); diff --git a/public/javascripts/lotOccupancyEdit.min.js b/public/javascripts/lotOccupancyEdit.min.js deleted file mode 100644 index 73b4437e..00000000 --- a/public/javascripts/lotOccupancyEdit.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e,t,n,c,o;const a=exports.los,l=document.querySelector("#lotOccupancy--lotOccupancyId").value,s=""===l;let r=s;function i(){var e;a.setUnsavedChanges(),null===(e=document.querySelector("button[type='submit'][form='form--lotOccupancy']"))||void 0===e||e.classList.remove("is-light")}function u(){var e;a.clearUnsavedChanges(),null===(e=document.querySelector("button[type='submit'][form='form--lotOccupancy']"))||void 0===e||e.classList.add("is-light")}const d=document.querySelector("#form--lotOccupancy");d.addEventListener("submit",e=>{e.preventDefault(),cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/${s?"doCreateLotOccupancy":"doUpdateLotOccupancy"}`,d,e=>{var t;const n=e;n.success?(u(),s||r?window.location.href=a.getLotOccupancyURL(n.lotOccupancyId,!0,!0):bulmaJS.alert({message:`${a.escapedAliases.Occupancy} Updated Successfully`,contextualColorName:"success"})):bulmaJS.alert({title:`Error Saving ${a.escapedAliases.Occupancy}`,message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})});const p=d.querySelectorAll("input, select");for(const e of p)e.addEventListener("change",i);function m(){cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doCopyLotOccupancy`,{lotOccupancyId:l},e=>{var t;const n=e;n.success?(u(),window.location.href=a.getLotOccupancyURL(n.lotOccupancyId,!0)):bulmaJS.alert({title:"Error Copying Record",message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}null===(S=document.querySelector("#button--copyLotOccupancy"))||void 0===S||S.addEventListener("click",e=>{e.preventDefault(),a.hasUnsavedChanges()?bulmaJS.alert({title:"Unsaved Changes",message:"Please save all unsaved changes before continuing.",contextualColorName:"warning"}):bulmaJS.confirm({title:`Copy ${a.escapedAliases.Occupancy} Record as New`,message:"Are you sure you want to copy this record to a new record?",contextualColorName:"info",okButton:{text:"Yes, Copy",callbackFunction:m}})}),null===(e=document.querySelector("#button--deleteLotOccupancy"))||void 0===e||e.addEventListener("click",e=>{e.preventDefault(),bulmaJS.confirm({title:`Delete ${a.escapedAliases.Occupancy} Record`,message:"Are you sure you want to delete this record?",contextualColorName:"warning",okButton:{text:"Yes, Delete",callbackFunction:function(){cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doDeleteLotOccupancy`,{lotOccupancyId:l},e=>{var t;const n=e;n.success?(u(),window.location.href=a.getLotOccupancyURL()):bulmaJS.alert({title:"Error Deleting Record",message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}}})}),null===(t=document.querySelector("#button--createWorkOrder"))||void 0===t||t.addEventListener("click",e=>{let t;function n(e){e.preventDefault(),cityssm.postJSON(`${a.urlPrefix}/workOrders/doCreateWorkOrder`,e.currentTarget,e=>{const n=e;n.success?(t(),bulmaJS.confirm({title:"Work Order Created Successfully",message:"Would you like to open the work order now?",contextualColorName:"success",okButton:{text:"Yes, Open the Work Order",callbackFunction:()=>{window.location.href=a.getWorkOrderURL(n.workOrderId,!0)}}})):bulmaJS.alert({title:"Error Creating Work Order",message:n.errorMessage,contextualColorName:"danger"})})}e.preventDefault(),cityssm.openHtmlModal("lotOccupancy-createWorkOrder",{onshow(e){var t;e.querySelector("#workOrderCreate--lotOccupancyId").value=l,e.querySelector("#workOrderCreate--workOrderOpenDateString").value=cityssm.dateToString(new Date);const n=e.querySelector("#workOrderCreate--workOrderTypeId"),c=exports.workOrderTypes;1===c.length&&(n.innerHTML="");for(const e of c){const c=document.createElement("option");c.value=e.workOrderTypeId.toString(),c.textContent=null!==(t=e.workOrderType)&&void 0!==t?t:"",n.append(c)}},onshown(e,c){var o;t=c,bulmaJS.toggleHtmlClipped(),e.querySelector("#workOrderCreate--workOrderTypeId").focus(),null===(o=e.querySelector("form"))||void 0===o||o.addEventListener("submit",n)},onremoved(){bulmaJS.toggleHtmlClipped(),document.querySelector("#button--createWorkOrder").focus()}})});const y=document.querySelector("#lotOccupancy--occupancyTypeId");if(s){const e=document.querySelector("#container--lotOccupancyFields");y.addEventListener("change",()=>{""!==y.value?cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doGetOccupancyTypeFields`,{occupancyTypeId:y.value},t=>{var n,c;const o=t;if(0===o.occupancyTypeFields.length)return void(e.innerHTML=`
    \n

    There are no additional fields for this ${a.escapedAliases.occupancy} type.

    \n
    `);e.innerHTML="";let l="";for(const t of o.occupancyTypeFields){l+=`,${t.occupancyTypeFieldId.toString()}`;const o=`lotOccupancyFieldValue_${t.occupancyTypeFieldId.toString()}`,a=`lotOccupancy--${o}`,s=document.createElement("div");if(s.className="field",s.innerHTML=`
    `,s.querySelector("label").textContent=t.occupancyTypeField,""===(null!==(n=t.occupancyTypeFieldValues)&&void 0!==n?n:"")){const e=document.createElement("input");e.className="input",e.id=a,e.name=o,e.type="text",e.required=t.isRequired,e.minLength=t.minimumLength,e.maxLength=t.maximumLength,""!==(null!==(c=t.pattern)&&void 0!==c?c:"")&&(e.pattern=t.pattern),s.querySelector(".control").append(e)}else{s.querySelector(".control").innerHTML=`
    \n \n
    `;const e=s.querySelector("select");e.required=t.isRequired;const n=t.occupancyTypeFieldValues.split("\n");for(const t of n){const n=document.createElement("option");n.value=t,n.textContent=t,e.append(n)}}console.log(s),e.append(s)}e.insertAdjacentHTML("beforeend",``)}):e.innerHTML=`
    \n

    Select the ${a.escapedAliases.occupancy} type to load the available fields.

    \n
    `})}else{const e=y.value;y.addEventListener("change",()=>{y.value!==e&&bulmaJS.confirm({title:"Confirm Change",message:`Are you sure you want to change the ${a.escapedAliases.occupancy} type?\n\n This change affects the additional fields associated with this record, and may also affect the available fees.`,contextualColorName:"warning",okButton:{text:"Yes, Keep the Change",callbackFunction:()=>{r=!0}},cancelButton:{text:"Revert the Change",callbackFunction:()=>{y.value=e}}})})}const v=document.querySelector("#lotOccupancy--lotName");v.addEventListener("click",e=>{const t=e.currentTarget.value;let n,c,o,l;function s(e,t){document.querySelector("#lotOccupancy--lotId").value=e.toString(),document.querySelector("#lotOccupancy--lotName").value=t,i(),n()}function r(e){var t,n;e.preventDefault();const c=e.currentTarget;s(null!==(t=c.dataset.lotId)&&void 0!==t?t:"",null!==(n=c.dataset.lotName)&&void 0!==n?n:"")}function u(){l.innerHTML=a.getLoadingParagraphHTML("Searching..."),cityssm.postJSON(`${a.urlPrefix}/lots/doSearchLots`,o,e=>{var t,n;const c=e;if(0===c.count)return void(l.innerHTML='
    \n

    No results.

    \n
    ');const o=document.createElement("div");o.className="panel";for(const e of c.lots){const c=document.createElement("a");c.className="panel-block is-block",c.href="#",c.dataset.lotId=e.lotId.toString(),c.dataset.lotName=e.lotName,c.innerHTML=`
    \n
    \n ${cityssm.escapeHTML(null!==(t=e.lotName)&&void 0!==t?t:"")}
    \n ${cityssm.escapeHTML(null!==(n=e.mapName)&&void 0!==n?n:"")}\n
    \n
    \n ${cityssm.escapeHTML(e.lotStatus)}
    \n \n ${e.lotOccupancyCount>0?"Currently Occupied":""}\n \n
    \n
    `,c.addEventListener("click",r),o.append(c)}l.innerHTML="",l.append(o)})}function d(e){e.preventDefault();const t=c.querySelector("#lotCreate--lotName").value;cityssm.postJSON(`${a.urlPrefix}/lots/doCreateLot`,e.currentTarget,e=>{var n,c;const o=e;o.success?s(null!==(n=o.lotId)&&void 0!==n?n:"",t):bulmaJS.alert({title:`Error Creating ${a.escapedAliases.Lot}`,message:null!==(c=o.errorMessage)&&void 0!==c?c:"",contextualColorName:"danger"})})}cityssm.openHtmlModal("lotOccupancy-selectLot",{onshow(e){a.populateAliases(e)},onshown(e,a){var s,r;bulmaJS.toggleHtmlClipped(),c=e,n=a,bulmaJS.init(e);const i=e.querySelector("#lotSelect--lotName");""!==document.querySelector("#lotOccupancy--lotId").value&&(i.value=t),i.focus(),i.addEventListener("change",u);const p=e.querySelector("#lotSelect--occupancyStatus");if(p.addEventListener("change",u),""!==t&&(p.value=""),o=e.querySelector("#form--lotSelect"),l=e.querySelector("#resultsContainer--lotSelect"),o.addEventListener("submit",e=>{e.preventDefault()}),u(),exports.lotNamePattern){const t=exports.lotNamePattern;e.querySelector("#lotCreate--lotName").pattern=t.source}const m=e.querySelector("#lotCreate--lotTypeId");for(const e of exports.lotTypes){const t=document.createElement("option");t.value=e.lotTypeId.toString(),t.textContent=e.lotType,m.append(t)}const y=e.querySelector("#lotCreate--lotStatusId");for(const e of exports.lotStatuses){const t=document.createElement("option");t.value=e.lotStatusId.toString(),t.textContent=e.lotStatus,y.append(t)}const v=e.querySelector("#lotCreate--mapId");for(const e of exports.maps){const t=document.createElement("option");t.value=e.mapId.toString(),t.textContent=""===(null!==(s=e.mapName)&&void 0!==s?s:"")?"(No Name)":null!==(r=e.mapName)&&void 0!==r?r:"",v.append(t)}e.querySelector("#form--lotCreate").addEventListener("submit",d)},onremoved(){bulmaJS.toggleHtmlClipped()}})}),null===(n=document.querySelector(".is-lot-view-button"))||void 0===n||n.addEventListener("click",()=>{const e=document.querySelector("#lotOccupancy--lotId").value;""===e?bulmaJS.alert({message:`No ${a.escapedAliases.lot} selected.`,contextualColorName:"info"}):window.open(`${a.urlPrefix}/lots/${e}`)}),null===(c=document.querySelector(".is-clear-lot-button"))||void 0===c||c.addEventListener("click",()=>{v.disabled?bulmaJS.alert({message:"You need to unlock the field before clearing it.",contextualColorName:"info"}):(v.value=`(No ${a.escapedAliases.Lot})`,document.querySelector("#lotOccupancy--lotId").value="",i())}),a.initializeDatePickers(d),null===(o=document.querySelector("#lotOccupancy--occupancyStartDateString"))||void 0===o||o.addEventListener("change",()=>{const e=document.querySelector("#lotOccupancy--occupancyEndDateString").bulmaCalendar.datePicker;e.min=document.querySelector("#lotOccupancy--occupancyStartDateString").value,e.refresh()}),a.initializeUnlockFieldButtons(d),Object.defineProperty(exports,"__esModule",{value:!0});let f=exports.lotOccupancyOccupants;function O(e){var t,n;const c=Number.parseInt(null!==(n=null===(t=e.currentTarget.closest("tr"))||void 0===t?void 0:t.dataset.lotOccupantIndex)&&void 0!==n?n:"",10),o=f.find(e=>e.lotOccupantIndex===c);let s,r;function i(e){e.preventDefault(),cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doUpdateLotOccupancyOccupant`,s,e=>{var t;const n=e;n.success?(f=n.lotOccupancyOccupants,r(),h()):bulmaJS.alert({title:`Error Updating ${a.escapedAliases.Occupant}`,message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}cityssm.openHtmlModal("lotOccupancy-editOccupant",{onshow(e){var t,n,s,r,i,u,d,p,m,y,v,f,O,g,h,S;a.populateAliases(e),e.querySelector("#lotOccupancyOccupantEdit--lotOccupancyId").value=l,e.querySelector("#lotOccupancyOccupantEdit--lotOccupantIndex").value=c.toString();const b=e.querySelector("#lotOccupancyOccupantEdit--lotOccupantTypeId");let C=!1;for(const e of exports.lotOccupantTypes){const t=document.createElement("option");t.value=e.lotOccupantTypeId.toString(),t.textContent=e.lotOccupantType,t.dataset.occupantCommentTitle=e.occupantCommentTitle,t.dataset.fontAwesomeIconClass=e.fontAwesomeIconClass,e.lotOccupantTypeId===o.lotOccupantTypeId&&(t.selected=!0,C=!0),b.append(t)}if(!C){const e=document.createElement("option");e.value=null!==(n=null===(t=o.lotOccupantTypeId)||void 0===t?void 0:t.toString())&&void 0!==n?n:"",e.textContent=null!==(s=o.lotOccupantType)&&void 0!==s?s:"",e.dataset.occupantCommentTitle=o.occupantCommentTitle,e.dataset.fontAwesomeIconClass=o.fontAwesomeIconClass,e.selected=!0,b.append(e)}e.querySelector("#lotOccupancyOccupantEdit--fontAwesomeIconClass").innerHTML=``,e.querySelector("#lotOccupancyOccupantEdit--occupantName").value=null!==(i=o.occupantName)&&void 0!==i?i:"",e.querySelector("#lotOccupancyOccupantEdit--occupantFamilyName").value=null!==(u=o.occupantFamilyName)&&void 0!==u?u:"",e.querySelector("#lotOccupancyOccupantEdit--occupantAddress1").value=null!==(d=o.occupantAddress1)&&void 0!==d?d:"",e.querySelector("#lotOccupancyOccupantEdit--occupantAddress2").value=null!==(p=o.occupantAddress2)&&void 0!==p?p:"",e.querySelector("#lotOccupancyOccupantEdit--occupantCity").value=null!==(m=o.occupantCity)&&void 0!==m?m:"",e.querySelector("#lotOccupancyOccupantEdit--occupantProvince").value=null!==(y=o.occupantProvince)&&void 0!==y?y:"",e.querySelector("#lotOccupancyOccupantEdit--occupantPostalCode").value=null!==(v=o.occupantPostalCode)&&void 0!==v?v:"",e.querySelector("#lotOccupancyOccupantEdit--occupantPhoneNumber").value=null!==(f=o.occupantPhoneNumber)&&void 0!==f?f:"",e.querySelector("#lotOccupancyOccupantEdit--occupantEmailAddress").value=null!==(O=o.occupantEmailAddress)&&void 0!==O?O:"",e.querySelector("#lotOccupancyOccupantEdit--occupantCommentTitle").textContent=""===(null!==(g=o.occupantCommentTitle)&&void 0!==g?g:"")?"Comment":null!==(h=o.occupantCommentTitle)&&void 0!==h?h:"",e.querySelector("#lotOccupancyOccupantEdit--occupantComment").value=null!==(S=o.occupantComment)&&void 0!==S?S:""},onshown(e,t){bulmaJS.toggleHtmlClipped();const n=e.querySelector("#lotOccupancyOccupantEdit--lotOccupantTypeId");n.focus(),n.addEventListener("change",()=>{var t,c;const o=null!==(t=n.selectedOptions[0].dataset.fontAwesomeIconClass)&&void 0!==t?t:"user";e.querySelector("#lotOccupancyOccupantEdit--fontAwesomeIconClass").innerHTML=``;let a=null!==(c=n.selectedOptions[0].dataset.occupantCommentTitle)&&void 0!==c?c:"";""===a&&(a="Comment"),e.querySelector("#lotOccupancyOccupantEdit--occupantCommentTitle").textContent=a}),(s=e.querySelector("form")).addEventListener("submit",i),r=t},onremoved(){bulmaJS.toggleHtmlClipped()}})}function g(e){var t;const n=null===(t=e.currentTarget.closest("tr"))||void 0===t?void 0:t.dataset.lotOccupantIndex;bulmaJS.confirm({title:`Remove ${a.escapedAliases.Occupant}?`,message:`Are you sure you want to remove this ${a.escapedAliases.occupant}?`,okButton:{text:`Yes, Remove ${a.escapedAliases.Occupant}`,callbackFunction:function(){cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doDeleteLotOccupancyOccupant`,{lotOccupancyId:l,lotOccupantIndex:n},e=>{var t;const n=e;n.success?(f=n.lotOccupancyOccupants,h()):bulmaJS.alert({title:`Error Removing ${a.escapedAliases.Occupant}`,message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}},contextualColorName:"warning"})}function h(){var e,t,n,c,o,l,s,r,i,u,d,p,m,y,v,h,S,b,C,T,x,L,q;const N=document.querySelector("#container--lotOccupancyOccupants");if(cityssm.clearElement(N),0===f.length)return void(N.innerHTML=`
    \n

    There are no ${a.escapedAliases.occupants} associated with this record.

    \n
    `);const E=document.createElement("table");E.className="table is-fullwidth is-striped is-hoverable",E.innerHTML=`\n ${a.escapedAliases.Occupant}\n Address\n Other Contact\n Comment\n Options\n \n `;for(const N of f){const f=document.createElement("tr");f.dataset.lotOccupantIndex=null===(e=N.lotOccupantIndex)||void 0===e?void 0:e.toString(),f.innerHTML=`\n ${cityssm.escapeHTML(""===(null!==(t=N.occupantName)&&void 0!==t?t:"")&&""===(null!==(n=N.occupantFamilyName)&&void 0!==n?n:"")?"(No Name)":`${N.occupantName} ${N.occupantFamilyName}`)}
    \n \n \n ${cityssm.escapeHTML(null!==(o=N.lotOccupantType)&&void 0!==o?o:"")}\n \n \n ${""===(null!==(l=N.occupantAddress1)&&void 0!==l?l:"")?"":`${cityssm.escapeHTML(null!==(s=N.occupantAddress1)&&void 0!==s?s:"")}
    `}\n ${""===(null!==(r=N.occupantAddress2)&&void 0!==r?r:"")?"":`${cityssm.escapeHTML(null!==(i=N.occupantAddress2)&&void 0!==i?i:"")}
    `}\n ${""===(null!==(u=N.occupantCity)&&void 0!==u?u:"")?"":`${cityssm.escapeHTML(null!==(d=N.occupantCity)&&void 0!==d?d:"")}, `}\n ${cityssm.escapeHTML(null!==(p=N.occupantProvince)&&void 0!==p?p:"")}
    \n ${cityssm.escapeHTML(null!==(m=N.occupantPostalCode)&&void 0!==m?m:"")}\n \n ${""===(null!==(y=N.occupantPhoneNumber)&&void 0!==y?y:"")?"":`${cityssm.escapeHTML(null!==(v=N.occupantPhoneNumber)&&void 0!==v?v:"")}
    `}\n ${""===(null!==(h=N.occupantEmailAddress)&&void 0!==h?h:"")?"":cityssm.escapeHTML(null!==(S=N.occupantEmailAddress)&&void 0!==S?S:"")}\n \n \n ${cityssm.escapeHTML(null!==(T=N.occupantComment)&&void 0!==T?T:"")}\n \n \n
    \n \n \n
    \n `,null===(x=f.querySelector(".button--edit"))||void 0===x||x.addEventListener("click",O),null===(L=f.querySelector(".button--delete"))||void 0===L||L.addEventListener("click",g),null===(q=E.querySelector("tbody"))||void 0===q||q.append(f)}N.append(E)}if(delete exports.lotOccupancyOccupants,s){const e=document.querySelector("#lotOccupancy--lotOccupantTypeId");e.addEventListener("change",()=>{var t;const n=d.querySelectorAll("[data-table='LotOccupancyOccupant']");for(const t of n)t.disabled=""===e.value;let c=null!==(t=e.selectedOptions[0].dataset.occupantCommentTitle)&&void 0!==t?t:"";""===c&&(c="Comment"),d.querySelector("#lotOccupancy--occupantCommentTitle").textContent=c})}else h();if(null===(S=document.querySelector("#button--addOccupant"))||void 0===S||S.addEventListener("click",()=>{let e,t,n,c;function o(t){cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doAddLotOccupancyOccupant`,t,t=>{var n;const c=t;c.success?(f=c.lotOccupancyOccupants,e(),h()):bulmaJS.alert({title:`Error Adding ${a.escapedAliases.Occupant}`,message:null!==(n=c.errorMessage)&&void 0!==n?n:"",contextualColorName:"danger"})})}function s(e){e.preventDefault(),o(t)}let r=[];function i(e){var t,n;e.preventDefault();const c=e.currentTarget,s=r[Number.parseInt(null!==(t=c.dataset.index)&&void 0!==t?t:"",10)],i=(null===(n=c.closest(".modal"))||void 0===n?void 0:n.querySelector("#lotOccupancyOccupantCopy--lotOccupantTypeId")).value;""===i?bulmaJS.alert({title:`No ${a.escapedAliases.Occupant} Type Selected`,message:`Select a type to apply to the newly added ${a.escapedAliases.occupant}.`,contextualColorName:"warning"}):(s.lotOccupantTypeId=Number.parseInt(i,10),s.lotOccupancyId=Number.parseInt(l,10),o(s))}function u(e){e.preventDefault(),""!==n.querySelector("#lotOccupancyOccupantCopy--searchFilter").value?(c.innerHTML=a.getLoadingParagraphHTML("Searching..."),cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doSearchPastOccupants`,n,e=>{var t,n,o,a,l,s,u,d,p,m,y;r=e.occupants;const v=document.createElement("div");v.className="panel";for(const[e,c]of r.entries()){const r=document.createElement("a");r.className="panel-block is-block",r.href="#",r.dataset.index=e.toString(),r.innerHTML=`\n ${cityssm.escapeHTML(null!==(t=c.occupantName)&&void 0!==t?t:"")} ${cityssm.escapeHTML(null!==(n=c.occupantFamilyName)&&void 0!==n?n:"")}\n
    \n
    \n
    \n ${cityssm.escapeHTML(null!==(o=c.occupantAddress1)&&void 0!==o?o:"")}
    \n ${""===(null!==(a=c.occupantAddress2)&&void 0!==a?a:"")?"":`${cityssm.escapeHTML(null!==(l=c.occupantAddress2)&&void 0!==l?l:"")}
    `}${cityssm.escapeHTML(null!==(s=c.occupantCity)&&void 0!==s?s:"")}, ${cityssm.escapeHTML(null!==(u=c.occupantProvince)&&void 0!==u?u:"")}
    \n ${cityssm.escapeHTML(null!==(d=c.occupantPostalCode)&&void 0!==d?d:"")}\n
    \n
    \n ${""===(null!==(p=c.occupantPhoneNumber)&&void 0!==p?p:"")?"":`${cityssm.escapeHTML(null!==(m=c.occupantPhoneNumber)&&void 0!==m?m:"")}
    `}\n ${cityssm.escapeHTML(null!==(y=c.occupantEmailAddress)&&void 0!==y?y:"")}
    \n
    \n
    `,r.addEventListener("click",i),v.append(r)}c.innerHTML="",c.append(v)})):c.innerHTML='
    \n

    Enter a partial name or address in the search field above.

    \n
    '}cityssm.openHtmlModal("lotOccupancy-addOccupant",{onshow(e){a.populateAliases(e),e.querySelector("#lotOccupancyOccupantAdd--lotOccupancyId").value=l;const t=e.querySelector("#lotOccupancyOccupantAdd--lotOccupantTypeId"),n=e.querySelector("#lotOccupancyOccupantCopy--lotOccupantTypeId");for(const e of exports.lotOccupantTypes){const c=document.createElement("option");c.value=e.lotOccupantTypeId.toString(),c.textContent=e.lotOccupantType,c.dataset.occupantCommentTitle=e.occupantCommentTitle,c.dataset.fontAwesomeIconClass=e.fontAwesomeIconClass,t.append(c),n.append(c.cloneNode(!0))}e.querySelector("#lotOccupancyOccupantAdd--occupantCity").value=exports.occupantCityDefault,e.querySelector("#lotOccupancyOccupantAdd--occupantProvince").value=exports.occupantProvinceDefault},onshown(o,a){bulmaJS.toggleHtmlClipped(),bulmaJS.init(o);const l=o.querySelector("#lotOccupancyOccupantAdd--lotOccupantTypeId");l.focus(),l.addEventListener("change",()=>{var e,t;const n=null!==(e=l.selectedOptions[0].dataset.fontAwesomeIconClass)&&void 0!==e?e:"user";o.querySelector("#lotOccupancyOccupantAdd--fontAwesomeIconClass").innerHTML=``;let c=null!==(t=l.selectedOptions[0].dataset.occupantCommentTitle)&&void 0!==t?t:"";""===c&&(c="Comment"),o.querySelector("#lotOccupancyOccupantAdd--occupantCommentTitle").textContent=c}),(t=o.querySelector("#form--lotOccupancyOccupantAdd")).addEventListener("submit",s),c=o.querySelector("#lotOccupancyOccupantCopy--searchResults"),(n=o.querySelector("#form--lotOccupancyOccupantCopy")).addEventListener("submit",e=>{e.preventDefault()}),o.querySelector("#lotOccupancyOccupantCopy--searchFilter").addEventListener("change",u),e=a},onremoved(){bulmaJS.toggleHtmlClipped(),document.querySelector("#button--addOccupant").focus()}})}),!s){var S;Object.defineProperty(exports,"__esModule",{value:!0});let e=exports.lotOccupancyComments;function b(t){var n,c;const o=Number.parseInt(null!==(c=null===(n=t.currentTarget.closest("tr"))||void 0===n?void 0:n.dataset.lotOccupancyCommentId)&&void 0!==c?c:"",10),s=e.find(e=>e.lotOccupancyCommentId===o);let r,i;function u(t){t.preventDefault(),cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doUpdateLotOccupancyComment`,r,t=>{var n,c;const o=t;o.success?(e=null!==(n=o.lotOccupancyComments)&&void 0!==n?n:[],i(),T()):bulmaJS.alert({title:"Error Updating Comment",message:null!==(c=o.errorMessage)&&void 0!==c?c:"",contextualColorName:"danger"})})}cityssm.openHtmlModal("lotOccupancy-editComment",{onshow(e){var t,n,c,r;a.populateAliases(e),e.querySelector("#lotOccupancyCommentEdit--lotOccupancyId").value=l,e.querySelector("#lotOccupancyCommentEdit--lotOccupancyCommentId").value=o.toString(),e.querySelector("#lotOccupancyCommentEdit--lotOccupancyComment").value=null!==(t=s.lotOccupancyComment)&&void 0!==t?t:"";const i=e.querySelector("#lotOccupancyCommentEdit--lotOccupancyCommentDateString");i.value=null!==(n=s.lotOccupancyCommentDateString)&&void 0!==n?n:"";const u=cityssm.dateToString(new Date);i.max=s.lotOccupancyCommentDateString<=u?u:null!==(c=s.lotOccupancyCommentDateString)&&void 0!==c?c:"",e.querySelector("#lotOccupancyCommentEdit--lotOccupancyCommentTimeString").value=null!==(r=s.lotOccupancyCommentTimeString)&&void 0!==r?r:""},onshown(e,t){bulmaJS.toggleHtmlClipped(),a.initializeDatePickers(e),e.querySelector("#lotOccupancyCommentEdit--lotOccupancyComment").focus(),(r=e.querySelector("form")).addEventListener("submit",u),i=t},onremoved(){bulmaJS.toggleHtmlClipped()}})}function C(t){var n,c;const o=Number.parseInt(null!==(c=null===(n=t.currentTarget.closest("tr"))||void 0===n?void 0:n.dataset.lotOccupancyCommentId)&&void 0!==c?c:"",10);bulmaJS.confirm({title:"Remove Comment?",message:"Are you sure you want to remove this comment?",okButton:{text:"Yes, Remove Comment",callbackFunction:function(){cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doDeleteLotOccupancyComment`,{lotOccupancyId:l,lotOccupancyCommentId:o},t=>{var n;const c=t;c.success?(e=c.lotOccupancyComments,T()):bulmaJS.alert({title:"Error Removing Comment",message:null!==(n=c.errorMessage)&&void 0!==n?n:"",contextualColorName:"danger"})})}},contextualColorName:"warning"})}function T(){var t,n,c,o,a,l,s,r;const i=document.querySelector("#container--lotOccupancyComments");if(0===e.length)return void(i.innerHTML='
    \n

    There are no comments associated with this record.

    \n
    ');const u=document.createElement("table");u.className="table is-fullwidth is-striped is-hoverable",u.innerHTML='\n Commentor\n Comment Date\n Comment\n Options\n \n ';for(const i of e){const e=document.createElement("tr");e.dataset.lotOccupancyCommentId=null===(t=i.lotOccupancyCommentId)||void 0===t?void 0:t.toString(),e.innerHTML=`${cityssm.escapeHTML(null!==(n=i.recordCreate_userName)&&void 0!==n?n:"")}\n \n ${cityssm.escapeHTML(null!==(c=i.lotOccupancyCommentDateString)&&void 0!==c?c:"")}\n ${cityssm.escapeHTML(0===i.lotOccupancyCommentTime?"":null!==(o=i.lotOccupancyCommentTimePeriodString)&&void 0!==o?o:"")}\n \n ${cityssm.escapeHTML(null!==(a=i.lotOccupancyComment)&&void 0!==a?a:"")}\n \n
    \n \n \n
    \n `,null===(l=e.querySelector(".button--edit"))||void 0===l||l.addEventListener("click",b),null===(s=e.querySelector(".button--delete"))||void 0===s||s.addEventListener("click",C),null===(r=u.querySelector("tbody"))||void 0===r||r.append(e)}i.innerHTML="",i.append(u)}delete exports.lotOccupancyComments,null===(S=document.querySelector("#button--addComment"))||void 0===S||S.addEventListener("click",()=>{let t,n;function c(c){c.preventDefault(),cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doAddLotOccupancyComment`,t,t=>{var c;const o=t;o.success?(e=o.lotOccupancyComments,n(),T()):bulmaJS.alert({title:"Error Adding Comment",message:null!==(c=o.errorMessage)&&void 0!==c?c:"",contextualColorName:"danger"})})}cityssm.openHtmlModal("lotOccupancy-addComment",{onshow(e){a.populateAliases(e),e.querySelector("#lotOccupancyCommentAdd--lotOccupancyId").value=l},onshown(e,o){bulmaJS.toggleHtmlClipped(),e.querySelector("#lotOccupancyCommentAdd--lotOccupancyComment").focus(),(t=e.querySelector("form")).addEventListener("submit",c),n=o},onremoved:()=>{bulmaJS.toggleHtmlClipped(),document.querySelector("#button--addComment").focus()}})}),T(),Object.defineProperty(exports,"__esModule",{value:!0});let t=exports.lotOccupancyFees;delete exports.lotOccupancyFees;const n=document.querySelector("#container--lotOccupancyFees");function x(){var e,n,c;let o=0;for(const a of t)o+=((null!==(e=a.feeAmount)&&void 0!==e?e:0)+(null!==(n=a.taxAmount)&&void 0!==n?n:0))*(null!==(c=a.quantity)&&void 0!==c?c:0);return o}function L(e){var n,c;const o=Number.parseInt(null!==(c=null===(n=e.currentTarget.closest("tr"))||void 0===n?void 0:n.dataset.feeId)&&void 0!==c?c:"",10),s=t.find(e=>e.feeId===o);let r;function i(e){e.preventDefault(),cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doUpdateLotOccupancyFeeQuantity`,e.currentTarget,e=>{const n=e;n.success?(t=n.lotOccupancyFees,N(),r()):bulmaJS.alert({title:"Error Updating Quantity",message:"Please try again.",contextualColorName:"danger"})})}cityssm.openHtmlModal("lotOccupancy-editFeeQuantity",{onshow(e){var t,n;e.querySelector("#lotOccupancyFeeQuantity--lotOccupancyId").value=l,e.querySelector("#lotOccupancyFeeQuantity--feeId").value=s.feeId.toString(),e.querySelector("#lotOccupancyFeeQuantity--quantity").valueAsNumber=null!==(t=s.quantity)&&void 0!==t?t:0,e.querySelector("#lotOccupancyFeeQuantity--quantityUnit").textContent=null!==(n=s.quantityUnit)&&void 0!==n?n:""},onshown(e,t){var n;bulmaJS.toggleHtmlClipped(),r=t,e.querySelector("#lotOccupancyFeeQuantity--quantity").focus(),null===(n=e.querySelector("form"))||void 0===n||n.addEventListener("submit",i)},onremoved(){bulmaJS.toggleHtmlClipped()}})}function q(e){const n=e.currentTarget.closest(".container--lotOccupancyFee").dataset.feeId;bulmaJS.confirm({title:"Delete Fee",message:"Are you sure you want to delete this fee?",contextualColorName:"warning",okButton:{text:"Yes, Delete Fee",callbackFunction:function(){cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doDeleteLotOccupancyFee`,{lotOccupancyId:l,feeId:n},e=>{var n;const c=e;c.success?(t=c.lotOccupancyFees,N()):bulmaJS.alert({title:"Error Deleting Fee",message:null!==(n=c.errorMessage)&&void 0!==n?n:"",contextualColorName:"danger"})})}}})}function N(){var e,c,o,a,l,s,r,i,u,d,p,m,y,v,f;if(0===t.length)return n.innerHTML='
    \n

    There are no fees associated with this record.

    \n
    ',void M();n.innerHTML='\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    FeeUnit Cost×QuantityequalsTotalOptions
    Subtotal
    Tax
    Grand Total
    ';let O=0,g=0;for(const h of t){const t=document.createElement("tr");t.className="container--lotOccupancyFee",t.dataset.feeId=h.feeId.toString(),t.dataset.includeQuantity=null!==(e=h.includeQuantity)&&void 0!==e&&e?"1":"0",t.innerHTML=`\n ${cityssm.escapeHTML(null!==(c=h.feeName)&&void 0!==c?c:"")}
    \n ${cityssm.escapeHTML(null!==(o=h.feeCategory)&&void 0!==o?o:"")}\n \n ${1===h.quantity?"":`\n $${null===(a=h.feeAmount)||void 0===a?void 0:a.toFixed(2)}\n \n ×\n ${null===(l=h.quantity)||void 0===l?void 0:l.toString()}\n =`}\n \n $${((null!==(s=h.feeAmount)&&void 0!==s?s:0)*(null!==(r=h.quantity)&&void 0!==r?r:0)).toFixed(2)}\n \n \n
    \n ${null!==(i=h.includeQuantity)&&void 0!==i&&i?'':""}\n \n
    \n `,null===(u=t.querySelector(".button--editQuantity"))||void 0===u||u.addEventListener("click",L),null===(d=t.querySelector(".button--delete"))||void 0===d||d.addEventListener("click",q),null===(p=n.querySelector("tbody"))||void 0===p||p.append(t),O+=(null!==(m=h.feeAmount)&&void 0!==m?m:0)*(null!==(y=h.quantity)&&void 0!==y?y:0),g+=(null!==(v=h.taxAmount)&&void 0!==v?v:0)*(null!==(f=h.quantity)&&void 0!==f?f:0)}n.querySelector("#lotOccupancyFees--feeAmountTotal").textContent=`$${O.toFixed(2)}`,n.querySelector("#lotOccupancyFees--taxAmountTotal").textContent=`$${g.toFixed(2)}`,n.querySelector("#lotOccupancyFees--grandTotal").textContent=`$${(O+g).toFixed(2)}`,M()}const c=document.querySelector("#button--addFee");c.addEventListener("click",()=>{if(a.hasUnsavedChanges())return void bulmaJS.alert({message:"Please save all unsaved changes before adding fees.",contextualColorName:"warning"});let e,o,s;function r(e){var n;e.preventDefault();const c=Number.parseInt(null!==(n=e.currentTarget.dataset.feeCategoryId)&&void 0!==n?n:"",10);cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doAddLotOccupancyFeeCategory`,{lotOccupancyId:l,feeCategoryId:c},e=>{var n;const c=e;c.success?(t=c.lotOccupancyFees,N(),bulmaJS.alert({message:"Fee Group Added Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Adding Fee",message:null!==(n=c.errorMessage)&&void 0!==n?n:"",contextualColorName:"danger"})})}function i(e,n=1){cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doAddLotOccupancyFee`,{lotOccupancyId:l,feeId:e,quantity:n},e=>{var n;const c=e;c.success?(t=c.lotOccupancyFees,N(),d()):bulmaJS.alert({title:"Error Adding Fee",message:null!==(n=c.errorMessage)&&void 0!==n?n:"",contextualColorName:"danger"})})}function u(t){var n,c,o;t.preventDefault();const a=Number.parseInt(null!==(n=t.currentTarget.dataset.feeId)&&void 0!==n?n:"",10),l=Number.parseInt(null!==(c=t.currentTarget.dataset.feeCategoryId)&&void 0!==c?c:"",10),s=e.find(e=>e.feeCategoryId===l).fees.find(e=>e.feeId===a);null!==(o=s.includeQuantity)&&void 0!==o&&o?function(e){let t,n;function c(c){c.preventDefault(),i(e.feeId,t.value),n()}cityssm.openHtmlModal("lotOccupancy-setFeeQuantity",{onshow(t){var n;t.querySelector("#lotOccupancyFeeQuantity--quantityUnit").textContent=null!==(n=e.quantityUnit)&&void 0!==n?n:""},onshown(e,o){var a;n=o,t=e.querySelector("#lotOccupancyFeeQuantity--quantity"),null===(a=e.querySelector("form"))||void 0===a||a.addEventListener("submit",c)}})}(s):i(a)}function d(){var t,c,a,l,i,d,p,m;const y=o.value.trim().toLowerCase().split(" ");s.innerHTML="";for(const o of e){const e=document.createElement("div");e.className="container--feeCategory",e.dataset.feeCategoryId=o.feeCategoryId.toString(),e.innerHTML=`
    \n
    \n

    \n ${cityssm.escapeHTML(null!==(t=o.feeCategory)&&void 0!==t?t:"")}\n

    \n
    \n
    \n
    `,o.isGroupedFee&&(null===(c=e.querySelector(".columns"))||void 0===c||c.insertAdjacentHTML("beforeend",`
    \n \n
    `),null===(a=e.querySelector("button"))||void 0===a||a.addEventListener("click",r));let v=!1;for(const t of o.fees){if(null!==n.querySelector(`.container--lotOccupancyFee[data-fee-id='${t.feeId}'][data-include-quantity='0']`))continue;let c=!0;const a=`${null!==(l=o.feeCategory)&&void 0!==l?l:""} ${null!==(i=t.feeName)&&void 0!==i?i:""} ${null!==(d=t.feeDescription)&&void 0!==d?d:""}`.toLowerCase();for(const e of y)if(!a.includes(e)){c=!1;break}if(!c)continue;v=!0;const s=document.createElement(o.isGroupedFee?"div":"a");s.className="panel-block is-block container--fee",s.dataset.feeId=t.feeId.toString(),s.dataset.feeCategoryId=o.feeCategoryId.toString(),s.innerHTML=`${cityssm.escapeHTML(null!==(p=t.feeName)&&void 0!==p?p:"")}
    \n \n ${cityssm.escapeHTML(null!==(m=t.feeDescription)&&void 0!==m?m:"").replaceAll("\n","
    ")}\n
    `,o.isGroupedFee||(s.href="#",s.addEventListener("click",u)),e.querySelector(".panel").append(s)}v&&s.append(e)}}cityssm.openHtmlModal("lotOccupancy-addFee",{onshow(t){o=t.querySelector("#feeSelect--feeName"),s=t.querySelector("#resultsContainer--feeSelect"),cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doGetFees`,{lotOccupancyId:l},t=>{e=t.feeCategories,o.disabled=!1,o.addEventListener("keyup",d),o.focus(),d()})},onshown(){bulmaJS.toggleHtmlClipped()},onhidden(){N()},onremoved(){bulmaJS.toggleHtmlClipped(),c.focus()}})});let o=exports.lotOccupancyTransactions;delete exports.lotOccupancyTransactions;const s=document.querySelector("#container--lotOccupancyTransactions");function E(e){var t,n;const c=Number.parseInt(null!==(n=null===(t=e.currentTarget.closest("tr"))||void 0===t?void 0:t.dataset.transactionIndex)&&void 0!==n?n:"",10),s=o.find(e=>e.transactionIndex===c);let r;function i(e){e.preventDefault(),cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doUpdateLotOccupancyTransaction`,e.currentTarget,e=>{const t=e;t.success?(o=t.lotOccupancyTransactions,M(),r()):bulmaJS.alert({title:"Error Updating Transaction",message:"Please try again.",contextualColorName:"danger"})})}cityssm.openHtmlModal("lotOccupancy-editTransaction",{onshow(e){var t,n,c,o,r,i;a.populateAliases(e),e.querySelector("#lotOccupancyTransactionEdit--lotOccupancyId").value=l,e.querySelector("#lotOccupancyTransactionEdit--transactionIndex").value=null!==(n=null===(t=s.transactionIndex)||void 0===t?void 0:t.toString())&&void 0!==n?n:"",e.querySelector("#lotOccupancyTransactionEdit--transactionAmount").value=s.transactionAmount.toFixed(2),e.querySelector("#lotOccupancyTransactionEdit--externalReceiptNumber").value=null!==(c=s.externalReceiptNumber)&&void 0!==c?c:"",e.querySelector("#lotOccupancyTransactionEdit--transactionNote").value=null!==(o=s.transactionNote)&&void 0!==o?o:"",e.querySelector("#lotOccupancyTransactionEdit--transactionDateString").value=null!==(r=s.transactionDateString)&&void 0!==r?r:"",e.querySelector("#lotOccupancyTransactionEdit--transactionTimeString").value=null!==(i=s.transactionTimeString)&&void 0!==i?i:""},onshown(e,t){var n;bulmaJS.toggleHtmlClipped(),a.initializeDatePickers(e),e.querySelector("#lotOccupancyTransactionEdit--transactionAmount").focus(),null===(n=e.querySelector("form"))||void 0===n||n.addEventListener("submit",i),r=t},onremoved(){bulmaJS.toggleHtmlClipped()}})}function $(e){const t=e.currentTarget.closest(".container--lotOccupancyTransaction").dataset.transactionIndex;bulmaJS.confirm({title:"Delete Trasnaction",message:"Are you sure you want to delete this transaction?",contextualColorName:"warning",okButton:{text:"Yes, Delete Transaction",callbackFunction:function(){cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doDeleteLotOccupancyTransaction`,{lotOccupancyId:l,transactionIndex:t},e=>{var t;const n=e;n.success?(o=n.lotOccupancyTransactions,M()):bulmaJS.alert({title:"Error Deleting Transaction",message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}}})}function M(){var e,n,c,l,r,i,u;if(0===o.length)return void(s.innerHTML=`
    \n

    There are no transactions associated with this record.

    \n
    `);s.innerHTML=`\n \n \n \n \n \n \n \n \n \n \n \n \n
    Date${a.escapedAliases.ExternalReceiptNumber}AmountOptions
    Transaction Total
    `;let d=0;for(const t of o){d+=t.transactionAmount;const o=document.createElement("tr");o.className="container--lotOccupancyTransaction",o.dataset.transactionIndex=null===(e=t.transactionIndex)||void 0===e?void 0:e.toString();let p="";""!==t.externalReceiptNumber&&(p=cityssm.escapeHTML(null!==(n=t.externalReceiptNumber)&&void 0!==n?n:""),a.dynamicsGPIntegrationIsEnabled&&(void 0===t.dynamicsGPDocument?p+=' \n \n ':t.dynamicsGPDocument.documentTotal.toFixed(2)===t.transactionAmount.toFixed(2)?p+=' \n \n ':p+=` \n \n `),p+="
    "),o.innerHTML=`\n ${cityssm.escapeHTML(null!==(c=t.transactionDateString)&&void 0!==c?c:"")}\n \n \n ${p}\n ${cityssm.escapeHTML(null!==(l=t.transactionNote)&&void 0!==l?l:"")}\n \n \n $${cityssm.escapeHTML(t.transactionAmount.toFixed(2))}\n \n \n
    \n \n \n
    \n `,null===(r=o.querySelector(".button--edit"))||void 0===r||r.addEventListener("click",E),null===(i=o.querySelector(".button--delete"))||void 0===i||i.addEventListener("click",$),null===(u=s.querySelector("tbody"))||void 0===u||u.append(o)}s.querySelector("#lotOccupancyTransactions--grandTotal").textContent=`$${d.toFixed(2)}`;const p=x();p.toFixed(2)!==d.toFixed(2)&&s.insertAdjacentHTML("afterbegin",`
    \n
    \n
    \n
    \n
    Outstanding Balance
    \n
    \n
    \n
    \n $${cityssm.escapeHTML((p-d).toFixed(2))}\n
    \n
    \n
    \n
    `)}const r=document.querySelector("#button--addTransaction");r.addEventListener("click",()=>{let e,t,n;function c(e){e.preventDefault(),cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doAddLotOccupancyTransaction`,e.currentTarget,e=>{var t;const c=e;c.success?(o=c.lotOccupancyTransactions,n(),M()):bulmaJS.confirm({title:"Error Adding Transaction",message:null!==(t=c.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}function s(){var n,c;const o=t.value,l=null===(n=t.closest(".control"))||void 0===n?void 0:n.querySelector(".icon"),s=null===(c=t.closest(".field"))||void 0===c?void 0:c.querySelector(".help");if(""===o)return s.innerHTML=" ",void(l.innerHTML='');cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doGetDynamicsGPDocument`,{externalReceiptNumber:o},t=>{const n=t;n.success&&void 0!==n.dynamicsGPDocument?e.valueAsNumber===n.dynamicsGPDocument.documentTotal?(s.textContent="Matching Document Found",l.innerHTML=''):(s.textContent=`Matching Document: $${n.dynamicsGPDocument.documentTotal.toFixed(2)}`,l.innerHTML=''):(s.textContent="No Matching Document Found",l.innerHTML='')})}cityssm.openHtmlModal("lotOccupancy-addTransaction",{onshow(n){a.populateAliases(n),n.querySelector("#lotOccupancyTransactionAdd--lotOccupancyId").value=l.toString();const c=x(),r=function(){let e=0;for(const t of o)e+=t.transactionAmount;return e}();if((e=n.querySelector("#lotOccupancyTransactionAdd--transactionAmount")).min=(-1*r).toFixed(2),e.max=Math.max(c-r,0).toFixed(2),e.value=Math.max(c-r,0).toFixed(2),a.dynamicsGPIntegrationIsEnabled){const c=(t=n.querySelector("#lotOccupancyTransactionAdd--externalReceiptNumber")).closest(".control");c.classList.add("has-icons-right"),c.insertAdjacentHTML("beforeend",''),c.insertAdjacentHTML("afterend",'

    '),t.addEventListener("change",s),e.addEventListener("change",s),s()}},onshown(t,o){var a;bulmaJS.toggleHtmlClipped(),e.focus(),n=o,null===(a=t.querySelector("form"))||void 0===a||a.addEventListener("submit",c)},onremoved(){bulmaJS.toggleHtmlClipped(),r.focus()}})}),N()}})(); \ No newline at end of file diff --git a/public/javascripts/lotOccupancyEdit.ts b/public/javascripts/lotOccupancyEdit.ts new file mode 100644 index 00000000..b5f0560f --- /dev/null +++ b/public/javascripts/lotOccupancyEdit.ts @@ -0,0 +1,2797 @@ +/* eslint-disable @eslint-community/eslint-comments/disable-enable-pair */ +/* eslint-disable unicorn/prefer-module */ + +import type { BulmaJS } from '@cityssm/bulma-js/types.js' +import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' + +import type { LOS } from '../../types/globalTypes.js' +import type { + DynamicsGPDocument, + Fee, + FeeCategory, + Lot, + LotOccupancyComment, + LotOccupancyFee, + LotOccupancyOccupant, + LotOccupancyTransaction, + LotOccupantType, + LotStatus, + LotType, + MapRecord, + OccupancyTypeField, + WorkOrderType +} from '../../types/recordTypes.js' + +declare const cityssm: cityssmGlobal +declare const bulmaJS: BulmaJS +declare const exports: Record +;(() => { + const los = exports.los as LOS + + const lotOccupancyId = ( + document.querySelector('#lotOccupancy--lotOccupancyId') as HTMLInputElement + ).value + const isCreate = lotOccupancyId === '' + + /* + * Main form + */ + + let refreshAfterSave = isCreate + + function setUnsavedChanges(): void { + los.setUnsavedChanges() + document + .querySelector("button[type='submit'][form='form--lotOccupancy']") + ?.classList.remove('is-light') + } + + function clearUnsavedChanges(): void { + los.clearUnsavedChanges() + document + .querySelector("button[type='submit'][form='form--lotOccupancy']") + ?.classList.add('is-light') + } + + const formElement = document.querySelector( + '#form--lotOccupancy' + ) as HTMLFormElement + + formElement.addEventListener('submit', (formEvent) => { + formEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/${isCreate ? 'doCreateLotOccupancy' : 'doUpdateLotOccupancy'}`, + formElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + lotOccupancyId?: number + errorMessage?: string + } + + if (responseJSON.success) { + clearUnsavedChanges() + + if (isCreate || refreshAfterSave) { + window.location.href = los.getLotOccupancyURL( + responseJSON.lotOccupancyId, + true, + true + ) + } else { + bulmaJS.alert({ + message: `${los.escapedAliases.Occupancy} Updated Successfully`, + contextualColorName: 'success' + }) + } + } else { + bulmaJS.alert({ + title: `Error Saving ${los.escapedAliases.Occupancy}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + }) + + const formInputElements = formElement.querySelectorAll('input, select') + + for (const formInputElement of formInputElements) { + formInputElement.addEventListener('change', setUnsavedChanges) + } + + function doCopy(): void { + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doCopyLotOccupancy`, + { + lotOccupancyId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + lotOccupancyId?: number + } + + if (responseJSON.success) { + clearUnsavedChanges() + + window.location.href = los.getLotOccupancyURL( + responseJSON.lotOccupancyId, + true + ) + } else { + bulmaJS.alert({ + title: 'Error Copying Record', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + document + .querySelector('#button--copyLotOccupancy') + ?.addEventListener('click', (clickEvent) => { + clickEvent.preventDefault() + + if (los.hasUnsavedChanges()) { + bulmaJS.alert({ + title: 'Unsaved Changes', + message: 'Please save all unsaved changes before continuing.', + contextualColorName: 'warning' + }) + } else { + bulmaJS.confirm({ + title: `Copy ${los.escapedAliases.Occupancy} Record as New`, + message: 'Are you sure you want to copy this record to a new record?', + contextualColorName: 'info', + okButton: { + text: 'Yes, Copy', + callbackFunction: doCopy + } + }) + } + }) + + document + .querySelector('#button--deleteLotOccupancy') + ?.addEventListener('click', (clickEvent) => { + clickEvent.preventDefault() + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancy`, + { + lotOccupancyId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + } + + if (responseJSON.success) { + clearUnsavedChanges() + window.location.href = los.getLotOccupancyURL() + } else { + bulmaJS.alert({ + title: 'Error Deleting Record', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + bulmaJS.confirm({ + title: `Delete ${los.escapedAliases.Occupancy} Record`, + message: 'Are you sure you want to delete this record?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete', + callbackFunction: doDelete + } + }) + }) + + document + .querySelector('#button--createWorkOrder') + ?.addEventListener('click', (clickEvent) => { + clickEvent.preventDefault() + + let createCloseModalFunction: () => void + + function doCreate(formEvent: SubmitEvent): void { + formEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doCreateWorkOrder`, + formEvent.currentTarget, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + workOrderId?: number + } + + if (responseJSON.success) { + createCloseModalFunction() + + bulmaJS.confirm({ + title: 'Work Order Created Successfully', + message: 'Would you like to open the work order now?', + contextualColorName: 'success', + okButton: { + text: 'Yes, Open the Work Order', + callbackFunction: () => { + window.location.href = los.getWorkOrderURL( + responseJSON.workOrderId, + true + ) + } + } + }) + } else { + bulmaJS.alert({ + title: 'Error Creating Work Order', + message: responseJSON.errorMessage as string, + contextualColorName: 'danger' + }) + } + } + ) + } + + cityssm.openHtmlModal('lotOccupancy-createWorkOrder', { + onshow(modalElement) { + ;( + modalElement.querySelector( + '#workOrderCreate--lotOccupancyId' + ) as HTMLInputElement + ).value = lotOccupancyId + ;( + modalElement.querySelector( + '#workOrderCreate--workOrderOpenDateString' + ) as HTMLInputElement + ).value = cityssm.dateToString(new Date()) + + const workOrderTypeSelectElement = modalElement.querySelector( + '#workOrderCreate--workOrderTypeId' + ) as HTMLSelectElement + + const workOrderTypes = (exports as Record) + .workOrderTypes as WorkOrderType[] + + if (workOrderTypes.length === 1) { + workOrderTypeSelectElement.innerHTML = '' + } + + for (const workOrderType of workOrderTypes) { + const optionElement = document.createElement('option') + optionElement.value = workOrderType.workOrderTypeId.toString() + optionElement.textContent = workOrderType.workOrderType ?? '' + workOrderTypeSelectElement.append(optionElement) + } + }, + onshown(modalElement, closeModalFunction) { + createCloseModalFunction = closeModalFunction + bulmaJS.toggleHtmlClipped() + ;( + modalElement.querySelector( + '#workOrderCreate--workOrderTypeId' + ) as HTMLSelectElement + ).focus() + + modalElement + .querySelector('form') + ?.addEventListener('submit', doCreate) + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + ;( + document.querySelector( + '#button--createWorkOrder' + ) as HTMLButtonElement + ).focus() + } + }) + }) + + // Occupancy Type + + const occupancyTypeIdElement = document.querySelector( + '#lotOccupancy--occupancyTypeId' + ) as HTMLSelectElement + + if (isCreate) { + const lotOccupancyFieldsContainerElement = document.querySelector( + '#container--lotOccupancyFields' + ) as HTMLElement + + occupancyTypeIdElement.addEventListener('change', () => { + if (occupancyTypeIdElement.value === '') { + // eslint-disable-next-line no-unsanitized/property + lotOccupancyFieldsContainerElement.innerHTML = `
    +

    Select the ${los.escapedAliases.occupancy} type to load the available fields.

    +
    ` + + return + } + + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doGetOccupancyTypeFields`, + { + occupancyTypeId: occupancyTypeIdElement.value + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + occupancyTypeFields: OccupancyTypeField[] + } + + if (responseJSON.occupancyTypeFields.length === 0) { + // eslint-disable-next-line no-unsanitized/property + lotOccupancyFieldsContainerElement.innerHTML = `
    +

    There are no additional fields for this ${los.escapedAliases.occupancy} type.

    +
    ` + + return + } + + lotOccupancyFieldsContainerElement.innerHTML = '' + + let occupancyTypeFieldIds = '' + + for (const occupancyTypeField of responseJSON.occupancyTypeFields) { + occupancyTypeFieldIds += `,${occupancyTypeField.occupancyTypeFieldId.toString()}` + + const fieldName = `lotOccupancyFieldValue_${occupancyTypeField.occupancyTypeFieldId.toString()}` + + const fieldId = `lotOccupancy--${fieldName}` + + const fieldElement = document.createElement('div') + fieldElement.className = 'field' + fieldElement.innerHTML = `
    ` + ;( + fieldElement.querySelector('label') as HTMLLabelElement + ).textContent = occupancyTypeField.occupancyTypeField as string + + if ((occupancyTypeField.occupancyTypeFieldValues ?? '') === '') { + const inputElement = document.createElement('input') + + inputElement.className = 'input' + + inputElement.id = fieldId + + inputElement.name = fieldName + + inputElement.type = 'text' + + inputElement.required = occupancyTypeField.isRequired as boolean + inputElement.minLength = + occupancyTypeField.minimumLength as number + inputElement.maxLength = + occupancyTypeField.maximumLength as number + + if ((occupancyTypeField.pattern ?? '') !== '') { + inputElement.pattern = occupancyTypeField.pattern as string + } + + ;(fieldElement.querySelector('.control') as HTMLElement).append( + inputElement + ) + } else { + ;( + fieldElement.querySelector('.control') as HTMLElement + ).innerHTML = `
    + +
    ` + + const selectElement = fieldElement.querySelector( + 'select' + ) as HTMLSelectElement + + selectElement.required = occupancyTypeField.isRequired as boolean + + const optionValues = ( + occupancyTypeField.occupancyTypeFieldValues as string + ).split('\n') + + for (const optionValue of optionValues) { + const optionElement = document.createElement('option') + optionElement.value = optionValue + optionElement.textContent = optionValue + selectElement.append(optionElement) + } + } + + console.log(fieldElement) + + lotOccupancyFieldsContainerElement.append(fieldElement) + } + + lotOccupancyFieldsContainerElement.insertAdjacentHTML( + 'beforeend', + // eslint-disable-next-line no-secrets/no-secrets + `` + ) + } + ) + }) + } else { + const originalOccupancyTypeId = occupancyTypeIdElement.value + + occupancyTypeIdElement.addEventListener('change', () => { + if (occupancyTypeIdElement.value !== originalOccupancyTypeId) { + bulmaJS.confirm({ + title: 'Confirm Change', + message: `Are you sure you want to change the ${los.escapedAliases.occupancy} type?\n + This change affects the additional fields associated with this record, and may also affect the available fees.`, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Keep the Change', + callbackFunction: () => { + refreshAfterSave = true + } + }, + cancelButton: { + text: 'Revert the Change', + callbackFunction: () => { + occupancyTypeIdElement.value = originalOccupancyTypeId + } + } + }) + } + }) + } + + // Lot Selector + + const lotNameElement = document.querySelector( + '#lotOccupancy--lotName' + ) as HTMLInputElement + + lotNameElement.addEventListener('click', (clickEvent) => { + const currentLotName = (clickEvent.currentTarget as HTMLInputElement).value + + let lotSelectCloseModalFunction: () => void + let lotSelectModalElement: HTMLElement + + let lotSelectFormElement: HTMLFormElement + let lotSelectResultsElement: HTMLElement + + function renderSelectedLotAndClose( + lotId: number | string, + lotName: string + ): void { + ;( + document.querySelector('#lotOccupancy--lotId') as HTMLInputElement + ).value = lotId.toString() + ;( + document.querySelector('#lotOccupancy--lotName') as HTMLInputElement + ).value = lotName + + setUnsavedChanges() + lotSelectCloseModalFunction() + } + + function selectExistingLot(clickEvent: Event): void { + clickEvent.preventDefault() + + const selectedLotElement = clickEvent.currentTarget as HTMLElement + + renderSelectedLotAndClose( + selectedLotElement.dataset.lotId ?? '', + selectedLotElement.dataset.lotName ?? '' + ) + } + + function searchLots(): void { + // eslint-disable-next-line no-unsanitized/property + lotSelectResultsElement.innerHTML = + los.getLoadingParagraphHTML('Searching...') + + cityssm.postJSON( + `${los.urlPrefix}/lots/doSearchLots`, + lotSelectFormElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + count: number + lots: Lot[] + } + + if (responseJSON.count === 0) { + lotSelectResultsElement.innerHTML = `
    +

    No results.

    +
    ` + + return + } + + const panelElement = document.createElement('div') + panelElement.className = 'panel' + + for (const lot of responseJSON.lots) { + const panelBlockElement = document.createElement('a') + panelBlockElement.className = 'panel-block is-block' + panelBlockElement.href = '#' + + panelBlockElement.dataset.lotId = lot.lotId.toString() + panelBlockElement.dataset.lotName = lot.lotName + + // eslint-disable-next-line no-unsanitized/property + panelBlockElement.innerHTML = `
    +
    + ${cityssm.escapeHTML(lot.lotName ?? '')}
    + ${cityssm.escapeHTML(lot.mapName ?? '')} +
    +
    + ${cityssm.escapeHTML(lot.lotStatus as string)}
    + + ${lot.lotOccupancyCount! > 0 ? 'Currently Occupied' : ''} + +
    +
    ` + + panelBlockElement.addEventListener('click', selectExistingLot) + + panelElement.append(panelBlockElement) + } + + lotSelectResultsElement.innerHTML = '' + lotSelectResultsElement.append(panelElement) + } + ) + } + + function createLotAndSelect(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + + const lotName = ( + lotSelectModalElement.querySelector( + '#lotCreate--lotName' + ) as HTMLInputElement + ).value + + cityssm.postJSON( + `${los.urlPrefix}/lots/doCreateLot`, + submitEvent.currentTarget, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + lotId?: number + } + + if (responseJSON.success) { + renderSelectedLotAndClose(responseJSON.lotId ?? '', lotName) + } else { + bulmaJS.alert({ + title: `Error Creating ${los.escapedAliases.Lot}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + cityssm.openHtmlModal('lotOccupancy-selectLot', { + onshow(modalElement) { + los.populateAliases(modalElement) + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped() + + lotSelectModalElement = modalElement + lotSelectCloseModalFunction = closeModalFunction + + bulmaJS.init(modalElement) + + // search Tab + + const lotNameFilterElement = modalElement.querySelector( + '#lotSelect--lotName' + ) as HTMLInputElement + + if ( + (document.querySelector('#lotOccupancy--lotId') as HTMLInputElement) + .value !== '' + ) { + lotNameFilterElement.value = currentLotName + } + + lotNameFilterElement.focus() + lotNameFilterElement.addEventListener('change', searchLots) + + const occupancyStatusFilterElement = modalElement.querySelector( + '#lotSelect--occupancyStatus' + ) as HTMLSelectElement + occupancyStatusFilterElement.addEventListener('change', searchLots) + + if (currentLotName !== '') { + occupancyStatusFilterElement.value = '' + } + + lotSelectFormElement = modalElement.querySelector( + '#form--lotSelect' + ) as HTMLFormElement + lotSelectResultsElement = modalElement.querySelector( + '#resultsContainer--lotSelect' + ) as HTMLElement + + lotSelectFormElement.addEventListener('submit', (submitEvent) => { + submitEvent.preventDefault() + }) + + searchLots() + + // Create Tab + + if (exports.lotNamePattern) { + const regex = exports.lotNamePattern as RegExp + + ;( + modalElement.querySelector( + '#lotCreate--lotName' + ) as HTMLInputElement + ).pattern = regex.source + } + + const lotTypeElement = modalElement.querySelector( + '#lotCreate--lotTypeId' + ) as HTMLSelectElement + + for (const lotType of exports.lotTypes as LotType[]) { + const optionElement = document.createElement('option') + optionElement.value = lotType.lotTypeId.toString() + optionElement.textContent = lotType.lotType + lotTypeElement.append(optionElement) + } + + const lotStatusElement = modalElement.querySelector( + '#lotCreate--lotStatusId' + ) as HTMLSelectElement + + for (const lotStatus of exports.lotStatuses as LotStatus[]) { + const optionElement = document.createElement('option') + optionElement.value = lotStatus.lotStatusId.toString() + optionElement.textContent = lotStatus.lotStatus + lotStatusElement.append(optionElement) + } + + const mapElement = modalElement.querySelector( + '#lotCreate--mapId' + ) as HTMLSelectElement + + for (const map of exports.maps as MapRecord[]) { + const optionElement = document.createElement('option') + optionElement.value = map.mapId!.toString() + optionElement.textContent = + (map.mapName ?? '') === '' ? '(No Name)' : map.mapName ?? '' + mapElement.append(optionElement) + } + + ;( + modalElement.querySelector('#form--lotCreate') as HTMLFormElement + ).addEventListener('submit', createLotAndSelect) + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + } + }) + }) + + document + .querySelector('.is-lot-view-button') + ?.addEventListener('click', () => { + const lotId = ( + document.querySelector('#lotOccupancy--lotId') as HTMLInputElement + ).value + + if (lotId === '') { + bulmaJS.alert({ + message: `No ${los.escapedAliases.lot} selected.`, + contextualColorName: 'info' + }) + } else { + window.open(`${los.urlPrefix}/lots/${lotId}`) + } + }) + + document + .querySelector('.is-clear-lot-button') + ?.addEventListener('click', () => { + if (lotNameElement.disabled) { + bulmaJS.alert({ + message: 'You need to unlock the field before clearing it.', + contextualColorName: 'info' + }) + } else { + lotNameElement.value = `(No ${los.escapedAliases.Lot})` + ;( + document.querySelector('#lotOccupancy--lotId') as HTMLInputElement + ).value = '' + + setUnsavedChanges() + } + }) + + // Start Date + + los.initializeDatePickers(formElement) + + document + .querySelector('#lotOccupancy--occupancyStartDateString') + ?.addEventListener('change', () => { + const endDatePicker = ( + document.querySelector( + '#lotOccupancy--occupancyEndDateString' + ) as HTMLInputElement + ).bulmaCalendar.datePicker + + endDatePicker.min = ( + document.querySelector( + '#lotOccupancy--occupancyStartDateString' + ) as HTMLInputElement + ).value + + endDatePicker.refresh() + }) + + los.initializeUnlockFieldButtons(formElement) + + /** + * Occupants + */ + ;(() => { + let lotOccupancyOccupants = + exports.lotOccupancyOccupants as LotOccupancyOccupant[] + + delete exports.lotOccupancyOccupants + + function openEditLotOccupancyOccupant(clickEvent: Event): void { + const lotOccupantIndex = Number.parseInt( + (clickEvent.currentTarget as HTMLElement).closest('tr')?.dataset + .lotOccupantIndex ?? '', + 10 + ) + + const lotOccupancyOccupant = lotOccupancyOccupants.find( + (currentLotOccupancyOccupant) => { + return ( + currentLotOccupancyOccupant.lotOccupantIndex === lotOccupantIndex + ) + } + ) as LotOccupancyOccupant + + let editFormElement: HTMLFormElement + let editCloseModalFunction: () => void + + function editOccupant(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyOccupant`, + editFormElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + lotOccupancyOccupants: LotOccupancyOccupant[] + } + + if (responseJSON.success) { + lotOccupancyOccupants = responseJSON.lotOccupancyOccupants + editCloseModalFunction() + renderLotOccupancyOccupants() + } else { + bulmaJS.alert({ + title: `Error Updating ${los.escapedAliases.Occupant}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + cityssm.openHtmlModal('lotOccupancy-editOccupant', { + onshow(modalElement) { + los.populateAliases(modalElement) + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--lotOccupancyId' + ) as HTMLInputElement + ).value = lotOccupancyId + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--lotOccupantIndex' + ) as HTMLInputElement + ).value = lotOccupantIndex.toString() + + const lotOccupantTypeSelectElement = modalElement.querySelector( + '#lotOccupancyOccupantEdit--lotOccupantTypeId' + ) as HTMLSelectElement + + let lotOccupantTypeSelected = false + + for (const lotOccupantType of exports.lotOccupantTypes as LotOccupantType[]) { + const optionElement = document.createElement('option') + optionElement.value = lotOccupantType.lotOccupantTypeId.toString() + optionElement.textContent = lotOccupantType.lotOccupantType + + optionElement.dataset.occupantCommentTitle = + lotOccupantType.occupantCommentTitle + + optionElement.dataset.fontAwesomeIconClass = + lotOccupantType.fontAwesomeIconClass + + if ( + lotOccupantType.lotOccupantTypeId === + lotOccupancyOccupant.lotOccupantTypeId + ) { + optionElement.selected = true + lotOccupantTypeSelected = true + } + + lotOccupantTypeSelectElement.append(optionElement) + } + + if (!lotOccupantTypeSelected) { + const optionElement = document.createElement('option') + + optionElement.value = + lotOccupancyOccupant.lotOccupantTypeId?.toString() ?? '' + optionElement.textContent = + lotOccupancyOccupant.lotOccupantType ?? '' + + optionElement.dataset.occupantCommentTitle = + lotOccupancyOccupant.occupantCommentTitle + + optionElement.dataset.fontAwesomeIconClass = + lotOccupancyOccupant.fontAwesomeIconClass + + optionElement.selected = true + + lotOccupantTypeSelectElement.append(optionElement) + } + + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--fontAwesomeIconClass' + ) as HTMLElement + ).innerHTML = + `` + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--occupantName' + ) as HTMLInputElement + ).value = lotOccupancyOccupant.occupantName ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--occupantFamilyName' + ) as HTMLInputElement + ).value = lotOccupancyOccupant.occupantFamilyName ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--occupantAddress1' + ) as HTMLInputElement + ).value = lotOccupancyOccupant.occupantAddress1 ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--occupantAddress2' + ) as HTMLInputElement + ).value = lotOccupancyOccupant.occupantAddress2 ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--occupantCity' + ) as HTMLInputElement + ).value = lotOccupancyOccupant.occupantCity ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--occupantProvince' + ) as HTMLInputElement + ).value = lotOccupancyOccupant.occupantProvince ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--occupantPostalCode' + ) as HTMLInputElement + ).value = lotOccupancyOccupant.occupantPostalCode ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--occupantPhoneNumber' + ) as HTMLInputElement + ).value = lotOccupancyOccupant.occupantPhoneNumber ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--occupantEmailAddress' + ) as HTMLInputElement + ).value = lotOccupancyOccupant.occupantEmailAddress ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--occupantCommentTitle' + ) as HTMLLabelElement + ).textContent = + (lotOccupancyOccupant.occupantCommentTitle ?? '') === '' + ? 'Comment' + : lotOccupancyOccupant.occupantCommentTitle ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--occupantComment' + ) as HTMLTextAreaElement + ).value = lotOccupancyOccupant.occupantComment ?? '' + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped() + + const lotOccupantTypeIdElement = modalElement.querySelector( + '#lotOccupancyOccupantEdit--lotOccupantTypeId' + ) as HTMLSelectElement + + lotOccupantTypeIdElement.focus() + + lotOccupantTypeIdElement.addEventListener('change', () => { + const fontAwesomeIconClass = + lotOccupantTypeIdElement.selectedOptions[0].dataset + .fontAwesomeIconClass ?? 'user' + + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--fontAwesomeIconClass' + ) as HTMLElement + ).innerHTML = + `` + + let occupantCommentTitle = + lotOccupantTypeIdElement.selectedOptions[0].dataset + .occupantCommentTitle ?? '' + if (occupantCommentTitle === '') { + occupantCommentTitle = 'Comment' + } + + ;( + modalElement.querySelector( + '#lotOccupancyOccupantEdit--occupantCommentTitle' + ) as HTMLLabelElement + ).textContent = occupantCommentTitle + }) + + editFormElement = modalElement.querySelector( + 'form' + ) as HTMLFormElement + editFormElement.addEventListener('submit', editOccupant) + + editCloseModalFunction = closeModalFunction + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + } + }) + } + + function deleteLotOccupancyOccupant(clickEvent: Event): void { + const lotOccupantIndex = ( + clickEvent.currentTarget as HTMLElement + ).closest('tr')?.dataset.lotOccupantIndex + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyOccupant`, + { + lotOccupancyId, + lotOccupantIndex + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + lotOccupancyOccupants: LotOccupancyOccupant[] + } + + if (responseJSON.success) { + lotOccupancyOccupants = responseJSON.lotOccupancyOccupants + renderLotOccupancyOccupants() + } else { + bulmaJS.alert({ + title: `Error Removing ${los.escapedAliases.Occupant}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + bulmaJS.confirm({ + title: `Remove ${los.escapedAliases.Occupant}?`, + message: `Are you sure you want to remove this ${los.escapedAliases.occupant}?`, + okButton: { + text: `Yes, Remove ${los.escapedAliases.Occupant}`, + callbackFunction: doDelete + }, + contextualColorName: 'warning' + }) + } + + function renderLotOccupancyOccupants(): void { + const occupantsContainer = document.querySelector( + '#container--lotOccupancyOccupants' + ) as HTMLElement + + cityssm.clearElement(occupantsContainer) + + if (lotOccupancyOccupants.length === 0) { + // eslint-disable-next-line no-unsanitized/property + occupantsContainer.innerHTML = `
    +

    There are no ${los.escapedAliases.occupants} associated with this record.

    +
    ` + + return + } + + const tableElement = document.createElement('table') + tableElement.className = 'table is-fullwidth is-striped is-hoverable' + + // eslint-disable-next-line no-unsanitized/property + tableElement.innerHTML = ` + ${los.escapedAliases.Occupant} + Address + Other Contact + Comment + Options + + ` + + for (const lotOccupancyOccupant of lotOccupancyOccupants) { + const tableRowElement = document.createElement('tr') + tableRowElement.dataset.lotOccupantIndex = + lotOccupancyOccupant.lotOccupantIndex?.toString() + + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` + ${cityssm.escapeHTML( + (lotOccupancyOccupant.occupantName ?? '') === '' && + (lotOccupancyOccupant.occupantFamilyName ?? '') === '' + ? '(No Name)' + : `${lotOccupancyOccupant.occupantName} ${lotOccupancyOccupant.occupantFamilyName}` + )}
    + + + ${cityssm.escapeHTML(lotOccupancyOccupant.lotOccupantType ?? '')} + + + ${ + (lotOccupancyOccupant.occupantAddress1 ?? '') === '' + ? '' + : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress1 ?? '')}
    ` + } + ${ + (lotOccupancyOccupant.occupantAddress2 ?? '') === '' + ? '' + : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress2 ?? '')}
    ` + } + ${ + (lotOccupancyOccupant.occupantCity ?? '') === '' + ? '' + : `${cityssm.escapeHTML(lotOccupancyOccupant.occupantCity ?? '')}, ` + } + ${cityssm.escapeHTML(lotOccupancyOccupant.occupantProvince ?? '')}
    + ${cityssm.escapeHTML(lotOccupancyOccupant.occupantPostalCode ?? '')} + + ${ + (lotOccupancyOccupant.occupantPhoneNumber ?? '') === '' + ? '' + : `${cityssm.escapeHTML( + lotOccupancyOccupant.occupantPhoneNumber ?? '' + )}
    ` + } + ${ + (lotOccupancyOccupant.occupantEmailAddress ?? '') === '' + ? '' + : cityssm.escapeHTML( + lotOccupancyOccupant.occupantEmailAddress ?? '' + ) + } + + + ${cityssm.escapeHTML(lotOccupancyOccupant.occupantComment ?? '')} + + +
    + + +
    + ` + + tableRowElement + .querySelector('.button--edit') + ?.addEventListener('click', openEditLotOccupancyOccupant) + + tableRowElement + .querySelector('.button--delete') + ?.addEventListener('click', deleteLotOccupancyOccupant) + + tableElement.querySelector('tbody')?.append(tableRowElement) + } + + occupantsContainer.append(tableElement) + } + + if (isCreate) { + const lotOccupantTypeIdElement = document.querySelector( + '#lotOccupancy--lotOccupantTypeId' + ) as HTMLSelectElement + + lotOccupantTypeIdElement.addEventListener('change', () => { + const occupantFields: NodeListOf< + HTMLInputElement | HTMLTextAreaElement + > = formElement.querySelectorAll("[data-table='LotOccupancyOccupant']") + + for (const occupantField of occupantFields) { + occupantField.disabled = lotOccupantTypeIdElement.value === '' + } + + let occupantCommentTitle = + lotOccupantTypeIdElement.selectedOptions[0].dataset + .occupantCommentTitle ?? '' + if (occupantCommentTitle === '') { + occupantCommentTitle = 'Comment' + } + + ;( + formElement.querySelector( + '#lotOccupancy--occupantCommentTitle' + ) as HTMLElement + ).textContent = occupantCommentTitle + }) + } else { + renderLotOccupancyOccupants() + } + + document + .querySelector('#button--addOccupant') + ?.addEventListener('click', () => { + let addCloseModalFunction: () => void + + let addFormElement: HTMLFormElement + + let searchFormElement: HTMLFormElement + let searchResultsElement: HTMLElement + + function addOccupant( + formOrObject: HTMLFormElement | LotOccupancyOccupant + ): void { + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doAddLotOccupancyOccupant`, + formOrObject, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + lotOccupancyOccupants: LotOccupancyOccupant[] + } + + if (responseJSON.success) { + lotOccupancyOccupants = responseJSON.lotOccupancyOccupants + addCloseModalFunction() + renderLotOccupancyOccupants() + } else { + bulmaJS.alert({ + title: `Error Adding ${los.escapedAliases.Occupant}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + function addOccupantFromForm(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + addOccupant(addFormElement) + } + + let pastOccupantSearchResults: LotOccupancyOccupant[] = [] + + function addOccupantFromCopy(clickEvent: MouseEvent): void { + clickEvent.preventDefault() + + const panelBlockElement = clickEvent.currentTarget as HTMLElement + + const occupant = + pastOccupantSearchResults[ + Number.parseInt(panelBlockElement.dataset.index ?? '', 10) + ] + + const lotOccupantTypeId = ( + panelBlockElement + .closest('.modal') + ?.querySelector( + '#lotOccupancyOccupantCopy--lotOccupantTypeId' + ) as HTMLSelectElement + ).value + + if (lotOccupantTypeId === '') { + bulmaJS.alert({ + title: `No ${los.escapedAliases.Occupant} Type Selected`, + message: `Select a type to apply to the newly added ${los.escapedAliases.occupant}.`, + contextualColorName: 'warning' + }) + } else { + occupant.lotOccupantTypeId = Number.parseInt(lotOccupantTypeId, 10) + occupant.lotOccupancyId = Number.parseInt(lotOccupancyId, 10) + addOccupant(occupant) + } + } + + function searchOccupants(event: Event): void { + event.preventDefault() + + if ( + ( + searchFormElement.querySelector( + '#lotOccupancyOccupantCopy--searchFilter' + ) as HTMLInputElement + ).value === '' + ) { + searchResultsElement.innerHTML = `
    +

    Enter a partial name or address in the search field above.

    +
    ` + + return + } + + // eslint-disable-next-line no-unsanitized/property + searchResultsElement.innerHTML = + los.getLoadingParagraphHTML('Searching...') + + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doSearchPastOccupants`, + searchFormElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + occupants: LotOccupancyOccupant[] + } + + pastOccupantSearchResults = responseJSON.occupants + + const panelElement = document.createElement('div') + panelElement.className = 'panel' + + for (const [ + index, + occupant + ] of pastOccupantSearchResults.entries()) { + const panelBlockElement = document.createElement('a') + panelBlockElement.className = 'panel-block is-block' + panelBlockElement.href = '#' + panelBlockElement.dataset.index = index.toString() + + // eslint-disable-next-line no-unsanitized/property + panelBlockElement.innerHTML = ` + ${cityssm.escapeHTML(occupant.occupantName ?? '')} ${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')} +
    +
    +
    + ${cityssm.escapeHTML(occupant.occupantAddress1 ?? '')}
    + ${ + (occupant.occupantAddress2 ?? '') === '' + ? '' + : `${cityssm.escapeHTML(occupant.occupantAddress2 ?? '')}
    ` + }${cityssm.escapeHTML(occupant.occupantCity ?? '')}, ${cityssm.escapeHTML(occupant.occupantProvince ?? '')}
    + ${cityssm.escapeHTML(occupant.occupantPostalCode ?? '')} +
    +
    + ${ + (occupant.occupantPhoneNumber ?? '') === '' + ? '' + : `${cityssm.escapeHTML(occupant.occupantPhoneNumber ?? '')}
    ` + } + ${cityssm.escapeHTML(occupant.occupantEmailAddress ?? '')}
    +
    +
    ` + + panelBlockElement.addEventListener('click', addOccupantFromCopy) + + panelElement.append(panelBlockElement) + } + + searchResultsElement.innerHTML = '' + searchResultsElement.append(panelElement) + } + ) + } + + cityssm.openHtmlModal('lotOccupancy-addOccupant', { + onshow(modalElement) { + los.populateAliases(modalElement) + ;( + modalElement.querySelector( + '#lotOccupancyOccupantAdd--lotOccupancyId' + ) as HTMLInputElement + ).value = lotOccupancyId + + const lotOccupantTypeSelectElement = modalElement.querySelector( + '#lotOccupancyOccupantAdd--lotOccupantTypeId' + ) as HTMLSelectElement + + const lotOccupantTypeCopySelectElement = modalElement.querySelector( + '#lotOccupancyOccupantCopy--lotOccupantTypeId' + ) as HTMLSelectElement + + for (const lotOccupantType of exports.lotOccupantTypes as LotOccupantType[]) { + const optionElement = document.createElement('option') + optionElement.value = lotOccupantType.lotOccupantTypeId.toString() + optionElement.textContent = lotOccupantType.lotOccupantType + + optionElement.dataset.occupantCommentTitle = + lotOccupantType.occupantCommentTitle + + optionElement.dataset.fontAwesomeIconClass = + lotOccupantType.fontAwesomeIconClass + + lotOccupantTypeSelectElement.append(optionElement) + + lotOccupantTypeCopySelectElement.append( + optionElement.cloneNode(true) + ) + } + + ;( + modalElement.querySelector( + '#lotOccupancyOccupantAdd--occupantCity' + ) as HTMLInputElement + ).value = exports.occupantCityDefault as string + ;( + modalElement.querySelector( + '#lotOccupancyOccupantAdd--occupantProvince' + ) as HTMLInputElement + ).value = exports.occupantProvinceDefault as string + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped() + bulmaJS.init(modalElement) + + const lotOccupantTypeIdElement = modalElement.querySelector( + '#lotOccupancyOccupantAdd--lotOccupantTypeId' + ) as HTMLSelectElement + + lotOccupantTypeIdElement.focus() + + lotOccupantTypeIdElement.addEventListener('change', () => { + const fontAwesomeIconClass = + lotOccupantTypeIdElement.selectedOptions[0].dataset + .fontAwesomeIconClass ?? 'user' + + ;( + modalElement.querySelector( + '#lotOccupancyOccupantAdd--fontAwesomeIconClass' + ) as HTMLElement + ).innerHTML = + `` + + let occupantCommentTitle = + lotOccupantTypeIdElement.selectedOptions[0].dataset + .occupantCommentTitle ?? '' + + if (occupantCommentTitle === '') { + occupantCommentTitle = 'Comment' + } + + ;( + modalElement.querySelector( + '#lotOccupancyOccupantAdd--occupantCommentTitle' + ) as HTMLElement + ).textContent = occupantCommentTitle + }) + + addFormElement = modalElement.querySelector( + '#form--lotOccupancyOccupantAdd' + ) as HTMLFormElement + addFormElement.addEventListener('submit', addOccupantFromForm) + + searchResultsElement = modalElement.querySelector( + '#lotOccupancyOccupantCopy--searchResults' + ) as HTMLElement + + searchFormElement = modalElement.querySelector( + '#form--lotOccupancyOccupantCopy' + ) as HTMLFormElement + searchFormElement.addEventListener('submit', (formEvent) => { + formEvent.preventDefault() + }) + ;( + modalElement.querySelector( + '#lotOccupancyOccupantCopy--searchFilter' + ) as HTMLInputElement + ).addEventListener('change', searchOccupants) + + addCloseModalFunction = closeModalFunction + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + ;( + document.querySelector( + '#button--addOccupant' + ) as HTMLButtonElement + ).focus() + } + }) + }) + })() + + if (!isCreate) { + /** + * Comments + */ + ;(() => { + let lotOccupancyComments = + exports.lotOccupancyComments as LotOccupancyComment[] + delete exports.lotOccupancyComments + + function openEditLotOccupancyComment(clickEvent: Event): void { + const lotOccupancyCommentId = Number.parseInt( + (clickEvent.currentTarget as HTMLElement).closest('tr')?.dataset + .lotOccupancyCommentId ?? '', + 10 + ) + + const lotOccupancyComment = lotOccupancyComments.find( + (currentLotOccupancyComment) => { + return ( + currentLotOccupancyComment.lotOccupancyCommentId === + lotOccupancyCommentId + ) + } + ) as LotOccupancyComment + + let editFormElement: HTMLFormElement + let editCloseModalFunction: () => void + + function editComment(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyComment`, + editFormElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + lotOccupancyComments?: LotOccupancyComment[] + } + + if (responseJSON.success) { + lotOccupancyComments = responseJSON.lotOccupancyComments ?? [] + editCloseModalFunction() + renderLotOccupancyComments() + } else { + bulmaJS.alert({ + title: 'Error Updating Comment', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + cityssm.openHtmlModal('lotOccupancy-editComment', { + onshow(modalElement) { + los.populateAliases(modalElement) + ;( + modalElement.querySelector( + '#lotOccupancyCommentEdit--lotOccupancyId' + ) as HTMLInputElement + ).value = lotOccupancyId + ;( + modalElement.querySelector( + '#lotOccupancyCommentEdit--lotOccupancyCommentId' + ) as HTMLInputElement + ).value = lotOccupancyCommentId.toString() + ;( + modalElement.querySelector( + '#lotOccupancyCommentEdit--lotOccupancyComment' + ) as HTMLInputElement + ).value = lotOccupancyComment.lotOccupancyComment ?? '' + + const lotOccupancyCommentDateStringElement = + modalElement.querySelector( + '#lotOccupancyCommentEdit--lotOccupancyCommentDateString' + ) as HTMLInputElement + + lotOccupancyCommentDateStringElement.value = + lotOccupancyComment.lotOccupancyCommentDateString ?? '' + + const currentDateString = cityssm.dateToString(new Date()) + + lotOccupancyCommentDateStringElement.max = + lotOccupancyComment.lotOccupancyCommentDateString! <= + currentDateString + ? currentDateString + : lotOccupancyComment.lotOccupancyCommentDateString ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyCommentEdit--lotOccupancyCommentTimeString' + ) as HTMLInputElement + ).value = lotOccupancyComment.lotOccupancyCommentTimeString ?? '' + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped() + + los.initializeDatePickers(modalElement) + ;( + modalElement.querySelector( + '#lotOccupancyCommentEdit--lotOccupancyComment' + ) as HTMLTextAreaElement + ).focus() + + editFormElement = modalElement.querySelector( + 'form' + ) as HTMLFormElement + + editFormElement.addEventListener('submit', editComment) + + editCloseModalFunction = closeModalFunction + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + } + }) + } + + function deleteLotOccupancyComment(clickEvent: Event): void { + const lotOccupancyCommentId = Number.parseInt( + (clickEvent.currentTarget as HTMLElement).closest('tr')?.dataset + .lotOccupancyCommentId ?? '', + 10 + ) + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyComment`, + { + lotOccupancyId, + lotOccupancyCommentId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + lotOccupancyComments: LotOccupancyComment[] + } + + if (responseJSON.success) { + lotOccupancyComments = responseJSON.lotOccupancyComments + renderLotOccupancyComments() + } else { + bulmaJS.alert({ + title: 'Error Removing Comment', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + bulmaJS.confirm({ + title: 'Remove Comment?', + message: 'Are you sure you want to remove this comment?', + okButton: { + text: 'Yes, Remove Comment', + callbackFunction: doDelete + }, + contextualColorName: 'warning' + }) + } + + function renderLotOccupancyComments(): void { + const containerElement = document.querySelector( + '#container--lotOccupancyComments' + ) as HTMLElement + + if (lotOccupancyComments.length === 0) { + containerElement.innerHTML = `
    +

    There are no comments associated with this record.

    +
    ` + return + } + + const tableElement = document.createElement('table') + tableElement.className = 'table is-fullwidth is-striped is-hoverable' + tableElement.innerHTML = ` + Commentor + Comment Date + Comment + Options + + ` + + for (const lotOccupancyComment of lotOccupancyComments) { + const tableRowElement = document.createElement('tr') + tableRowElement.dataset.lotOccupancyCommentId = + lotOccupancyComment.lotOccupancyCommentId?.toString() + + tableRowElement.innerHTML = `${cityssm.escapeHTML(lotOccupancyComment.recordCreate_userName ?? '')} + + ${cityssm.escapeHTML( + lotOccupancyComment.lotOccupancyCommentDateString ?? '' + )} + ${cityssm.escapeHTML( + lotOccupancyComment.lotOccupancyCommentTime === 0 + ? '' + : lotOccupancyComment.lotOccupancyCommentTimePeriodString ?? '' + )} + + ${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyComment ?? '')} + +
    + + +
    + ` + + tableRowElement + .querySelector('.button--edit') + ?.addEventListener('click', openEditLotOccupancyComment) + + tableRowElement + .querySelector('.button--delete') + ?.addEventListener('click', deleteLotOccupancyComment) + + tableElement.querySelector('tbody')?.append(tableRowElement) + } + + containerElement.innerHTML = '' + containerElement.append(tableElement) + } + + document + .querySelector('#button--addComment') + ?.addEventListener('click', () => { + let addFormElement: HTMLFormElement + let addCloseModalFunction: () => void + + function addComment(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doAddLotOccupancyComment`, + addFormElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + lotOccupancyComments: LotOccupancyComment[] + } + + if (responseJSON.success) { + lotOccupancyComments = responseJSON.lotOccupancyComments + addCloseModalFunction() + renderLotOccupancyComments() + } else { + bulmaJS.alert({ + title: 'Error Adding Comment', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + cityssm.openHtmlModal('lotOccupancy-addComment', { + onshow(modalElement) { + los.populateAliases(modalElement) + ;( + modalElement.querySelector( + '#lotOccupancyCommentAdd--lotOccupancyId' + ) as HTMLInputElement + ).value = lotOccupancyId + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped() + ;( + modalElement.querySelector( + '#lotOccupancyCommentAdd--lotOccupancyComment' + ) as HTMLTextAreaElement + ).focus() + + addFormElement = modalElement.querySelector( + 'form' + ) as HTMLFormElement + + addFormElement.addEventListener('submit', addComment) + + addCloseModalFunction = closeModalFunction + }, + onremoved: () => { + bulmaJS.toggleHtmlClipped() + ;( + document.querySelector( + '#button--addComment' + ) as HTMLButtonElement + ).focus() + } + }) + }) + + renderLotOccupancyComments() + })() + + /** + * Fees + */ + ;(() => { + let lotOccupancyFees = exports.lotOccupancyFees as LotOccupancyFee[] + delete exports.lotOccupancyFees + + const lotOccupancyFeesContainerElement = document.querySelector( + '#container--lotOccupancyFees' + ) as HTMLElement + + function getFeeGrandTotal(): number { + let feeGrandTotal = 0 + + for (const lotOccupancyFee of lotOccupancyFees) { + feeGrandTotal += + ((lotOccupancyFee.feeAmount ?? 0) + + (lotOccupancyFee.taxAmount ?? 0)) * + (lotOccupancyFee.quantity ?? 0) + } + + return feeGrandTotal + } + + function editLotOccupancyFeeQuantity(clickEvent: Event): void { + const feeId = Number.parseInt( + (clickEvent.currentTarget as HTMLButtonElement).closest('tr')?.dataset + .feeId ?? '', + 10 + ) + + const fee = lotOccupancyFees.find((possibleFee) => { + return possibleFee.feeId === feeId + }) as LotOccupancyFee + + let updateCloseModalFunction: () => void + + function doUpdateQuantity(formEvent: SubmitEvent): void { + formEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyFeeQuantity`, + formEvent.currentTarget, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + lotOccupancyFees: LotOccupancyFee[] + } + + if (responseJSON.success) { + lotOccupancyFees = responseJSON.lotOccupancyFees + renderLotOccupancyFees() + updateCloseModalFunction() + } else { + bulmaJS.alert({ + title: 'Error Updating Quantity', + message: 'Please try again.', + contextualColorName: 'danger' + }) + } + } + ) + } + + cityssm.openHtmlModal('lotOccupancy-editFeeQuantity', { + onshow(modalElement) { + ;( + modalElement.querySelector( + '#lotOccupancyFeeQuantity--lotOccupancyId' + ) as HTMLInputElement + ).value = lotOccupancyId + ;( + modalElement.querySelector( + '#lotOccupancyFeeQuantity--feeId' + ) as HTMLInputElement + ).value = fee.feeId.toString() + ;( + modalElement.querySelector( + '#lotOccupancyFeeQuantity--quantity' + ) as HTMLInputElement + ).valueAsNumber = fee.quantity ?? 0 + ;( + modalElement.querySelector( + '#lotOccupancyFeeQuantity--quantityUnit' + ) as HTMLElement + ).textContent = fee.quantityUnit ?? '' + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped() + + updateCloseModalFunction = closeModalFunction + ;( + modalElement.querySelector( + '#lotOccupancyFeeQuantity--quantity' + ) as HTMLInputElement + ).focus() + + modalElement + .querySelector('form') + ?.addEventListener('submit', doUpdateQuantity) + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + } + }) + } + + function deleteLotOccupancyFee(clickEvent: Event): void { + const feeId = ( + (clickEvent.currentTarget as HTMLElement).closest( + '.container--lotOccupancyFee' + ) as HTMLElement + ).dataset.feeId + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyFee`, + { + lotOccupancyId, + feeId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + lotOccupancyFees: LotOccupancyFee[] + } + + if (responseJSON.success) { + lotOccupancyFees = responseJSON.lotOccupancyFees + renderLotOccupancyFees() + } else { + bulmaJS.alert({ + title: 'Error Deleting Fee', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + bulmaJS.confirm({ + title: 'Delete Fee', + message: 'Are you sure you want to delete this fee?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Fee', + callbackFunction: doDelete + } + }) + } + + function renderLotOccupancyFees(): void { + if (lotOccupancyFees.length === 0) { + lotOccupancyFeesContainerElement.innerHTML = `
    +

    There are no fees associated with this record.

    +
    ` + + renderLotOccupancyTransactions() + + return + } + + // eslint-disable-next-line no-secrets/no-secrets + lotOccupancyFeesContainerElement.innerHTML = ` + + + + + + + + + + + + + + + + + + + + + + +
    FeeUnit Cost×QuantityequalsTotalOptions
    Subtotal
    Tax
    Grand Total
    ` + + let feeAmountTotal = 0 + let taxAmountTotal = 0 + + for (const lotOccupancyFee of lotOccupancyFees) { + const tableRowElement = document.createElement('tr') + tableRowElement.className = 'container--lotOccupancyFee' + tableRowElement.dataset.feeId = lotOccupancyFee.feeId.toString() + tableRowElement.dataset.includeQuantity = + lotOccupancyFee.includeQuantity ?? false ? '1' : '0' + + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` + ${cityssm.escapeHTML(lotOccupancyFee.feeName ?? '')}
    + ${cityssm.escapeHTML(lotOccupancyFee.feeCategory ?? '')} + + ${ + lotOccupancyFee.quantity === 1 + ? '' + : ` + $${lotOccupancyFee.feeAmount?.toFixed(2)} + + × + ${lotOccupancyFee.quantity?.toString()} + =` + } + + $${((lotOccupancyFee.feeAmount ?? 0) * (lotOccupancyFee.quantity ?? 0)).toFixed(2)} + + +
    + ${ + lotOccupancyFee.includeQuantity ?? false + ? `` + : '' + } + +
    + ` + + tableRowElement + .querySelector('.button--editQuantity') + ?.addEventListener('click', editLotOccupancyFeeQuantity) + + tableRowElement + .querySelector('.button--delete') + ?.addEventListener('click', deleteLotOccupancyFee) + + lotOccupancyFeesContainerElement + .querySelector('tbody') + ?.append(tableRowElement) + + feeAmountTotal += + (lotOccupancyFee.feeAmount ?? 0) * (lotOccupancyFee.quantity ?? 0) + + taxAmountTotal += + (lotOccupancyFee.taxAmount ?? 0) * (lotOccupancyFee.quantity ?? 0) + } + + ;( + lotOccupancyFeesContainerElement.querySelector( + '#lotOccupancyFees--feeAmountTotal' + ) as HTMLElement + ).textContent = `$${feeAmountTotal.toFixed(2)}` + ;( + lotOccupancyFeesContainerElement.querySelector( + '#lotOccupancyFees--taxAmountTotal' + ) as HTMLElement + ).textContent = `$${taxAmountTotal.toFixed(2)}` + ;( + lotOccupancyFeesContainerElement.querySelector( + '#lotOccupancyFees--grandTotal' + ) as HTMLElement + ).textContent = `$${(feeAmountTotal + taxAmountTotal).toFixed(2)}` + + renderLotOccupancyTransactions() + } + + const addFeeButtonElement = document.querySelector( + '#button--addFee' + ) as HTMLButtonElement + + addFeeButtonElement.addEventListener('click', () => { + if (los.hasUnsavedChanges()) { + bulmaJS.alert({ + message: 'Please save all unsaved changes before adding fees.', + contextualColorName: 'warning' + }) + return + } + + let feeCategories: FeeCategory[] + + let feeFilterElement: HTMLInputElement + let feeFilterResultsElement: HTMLElement + + function doAddFeeCategory(clickEvent: Event): void { + clickEvent.preventDefault() + + const feeCategoryId = Number.parseInt( + (clickEvent.currentTarget as HTMLElement).dataset.feeCategoryId ?? + '', + 10 + ) + + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doAddLotOccupancyFeeCategory`, + { + lotOccupancyId, + feeCategoryId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + lotOccupancyFees: LotOccupancyFee[] + } + + if (responseJSON.success) { + lotOccupancyFees = responseJSON.lotOccupancyFees + renderLotOccupancyFees() + + bulmaJS.alert({ + message: 'Fee Group Added Successfully', + contextualColorName: 'success' + }) + } else { + bulmaJS.alert({ + title: 'Error Adding Fee', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + function doAddFee(feeId: number, quantity: number | string = 1): void { + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doAddLotOccupancyFee`, + { + lotOccupancyId, + feeId, + quantity + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + lotOccupancyFees: LotOccupancyFee[] + } + + if (responseJSON.success) { + lotOccupancyFees = responseJSON.lotOccupancyFees + renderLotOccupancyFees() + filterFees() + } else { + bulmaJS.alert({ + title: 'Error Adding Fee', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + function doSetQuantityAndAddFee(fee: Fee): void { + let quantityElement: HTMLInputElement + let quantityCloseModalFunction: () => void + + function doSetQuantity(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + doAddFee(fee.feeId, quantityElement.value) + quantityCloseModalFunction() + } + + cityssm.openHtmlModal('lotOccupancy-setFeeQuantity', { + onshow(modalElement) { + ;( + modalElement.querySelector( + '#lotOccupancyFeeQuantity--quantityUnit' + ) as HTMLElement + ).textContent = fee.quantityUnit ?? '' + }, + onshown(modalElement, closeModalFunction) { + quantityCloseModalFunction = closeModalFunction + + quantityElement = modalElement.querySelector( + '#lotOccupancyFeeQuantity--quantity' + ) as HTMLInputElement + + modalElement + .querySelector('form') + ?.addEventListener('submit', doSetQuantity) + } + }) + } + + function tryAddFee(clickEvent: Event): void { + clickEvent.preventDefault() + + const feeId = Number.parseInt( + (clickEvent.currentTarget as HTMLElement).dataset.feeId ?? '', + 10 + ) + const feeCategoryId = Number.parseInt( + (clickEvent.currentTarget as HTMLElement).dataset.feeCategoryId ?? + '', + 10 + ) + + const feeCategory = feeCategories.find((currentFeeCategory) => { + return currentFeeCategory.feeCategoryId === feeCategoryId + }) as FeeCategory + + const fee = feeCategory.fees.find((currentFee) => { + return currentFee.feeId === feeId + }) as Fee + + if (fee.includeQuantity ?? false) { + doSetQuantityAndAddFee(fee) + } else { + doAddFee(feeId) + } + } + + function filterFees(): void { + const filterStringPieces = feeFilterElement.value + .trim() + .toLowerCase() + .split(' ') + + feeFilterResultsElement.innerHTML = '' + + for (const feeCategory of feeCategories) { + const categoryContainerElement = document.createElement('div') + + categoryContainerElement.className = 'container--feeCategory' + + categoryContainerElement.dataset.feeCategoryId = + feeCategory.feeCategoryId.toString() + + categoryContainerElement.innerHTML = `
    +
    +

    + ${cityssm.escapeHTML(feeCategory.feeCategory ?? '')} +

    +
    +
    +
    ` + + if (feeCategory.isGroupedFee) { + // eslint-disable-next-line no-unsanitized/method + categoryContainerElement + .querySelector('.columns') + ?.insertAdjacentHTML( + 'beforeend', + `
    + +
    ` + ) + + categoryContainerElement + .querySelector('button') + ?.addEventListener('click', doAddFeeCategory) + } + + let hasFees = false + + for (const fee of feeCategory.fees) { + // Don't include already applied fees that limit quantity + if ( + lotOccupancyFeesContainerElement.querySelector( + `.container--lotOccupancyFee[data-fee-id='${fee.feeId}'][data-include-quantity='0']` + ) !== null + ) { + continue + } + + let includeFee = true + + const feeSearchString = + `${feeCategory.feeCategory ?? ''} ${fee.feeName ?? ''} ${fee.feeDescription ?? ''}`.toLowerCase() + + for (const filterStringPiece of filterStringPieces) { + if (!feeSearchString.includes(filterStringPiece)) { + includeFee = false + break + } + } + + if (!includeFee) { + continue + } + + hasFees = true + + const panelBlockElement = document.createElement( + feeCategory.isGroupedFee ? 'div' : 'a' + ) + panelBlockElement.className = + 'panel-block is-block container--fee' + panelBlockElement.dataset.feeId = fee.feeId.toString() + panelBlockElement.dataset.feeCategoryId = + feeCategory.feeCategoryId.toString() + + // eslint-disable-next-line no-unsanitized/property + panelBlockElement.innerHTML = `${cityssm.escapeHTML(fee.feeName ?? '')}
    + + ${ + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + cityssm + .escapeHTML(fee.feeDescription ?? '') + .replaceAll('\n', '
    ') + } +
    ` + + if (!feeCategory.isGroupedFee) { + ;(panelBlockElement as HTMLAnchorElement).href = '#' + panelBlockElement.addEventListener('click', tryAddFee) + } + ;( + categoryContainerElement.querySelector('.panel') as HTMLElement + ).append(panelBlockElement) + } + + if (hasFees) { + feeFilterResultsElement.append(categoryContainerElement) + } + } + } + + cityssm.openHtmlModal('lotOccupancy-addFee', { + onshow(modalElement) { + feeFilterElement = modalElement.querySelector( + '#feeSelect--feeName' + ) as HTMLInputElement + + feeFilterResultsElement = modalElement.querySelector( + '#resultsContainer--feeSelect' + ) as HTMLElement + + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doGetFees`, + { + lotOccupancyId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + feeCategories: FeeCategory[] + } + + feeCategories = responseJSON.feeCategories + + feeFilterElement.disabled = false + feeFilterElement.addEventListener('keyup', filterFees) + feeFilterElement.focus() + + filterFees() + } + ) + }, + onshown() { + bulmaJS.toggleHtmlClipped() + }, + onhidden() { + renderLotOccupancyFees() + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + addFeeButtonElement.focus() + } + }) + }) + + let lotOccupancyTransactions = + exports.lotOccupancyTransactions as LotOccupancyTransaction[] + delete exports.lotOccupancyTransactions + + const lotOccupancyTransactionsContainerElement = document.querySelector( + '#container--lotOccupancyTransactions' + ) as HTMLElement + + function getTransactionGrandTotal(): number { + let transactionGrandTotal = 0 + + for (const lotOccupancyTransaction of lotOccupancyTransactions) { + transactionGrandTotal += lotOccupancyTransaction.transactionAmount + } + + return transactionGrandTotal + } + + function editLotOccupancyTransaction(clickEvent: Event): void { + const transactionIndex = Number.parseInt( + (clickEvent.currentTarget as HTMLButtonElement).closest('tr')?.dataset + .transactionIndex ?? '', + 10 + ) + + const transaction = lotOccupancyTransactions.find( + (possibleTransaction) => { + return possibleTransaction.transactionIndex === transactionIndex + } + ) as LotOccupancyTransaction + + let editCloseModalFunction: () => void + + function doEdit(formEvent: SubmitEvent): void { + formEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doUpdateLotOccupancyTransaction`, + formEvent.currentTarget, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + lotOccupancyTransactions: LotOccupancyTransaction[] + } + + if (responseJSON.success) { + lotOccupancyTransactions = responseJSON.lotOccupancyTransactions + renderLotOccupancyTransactions() + editCloseModalFunction() + } else { + bulmaJS.alert({ + title: 'Error Updating Transaction', + message: 'Please try again.', + contextualColorName: 'danger' + }) + } + } + ) + } + + cityssm.openHtmlModal('lotOccupancy-editTransaction', { + onshow(modalElement) { + los.populateAliases(modalElement) + ;( + modalElement.querySelector( + '#lotOccupancyTransactionEdit--lotOccupancyId' + ) as HTMLInputElement + ).value = lotOccupancyId + ;( + modalElement.querySelector( + '#lotOccupancyTransactionEdit--transactionIndex' + ) as HTMLInputElement + ).value = transaction.transactionIndex?.toString() ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyTransactionEdit--transactionAmount' + ) as HTMLInputElement + ).value = transaction.transactionAmount.toFixed(2) + ;( + modalElement.querySelector( + '#lotOccupancyTransactionEdit--externalReceiptNumber' + ) as HTMLInputElement + ).value = transaction.externalReceiptNumber ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyTransactionEdit--transactionNote' + ) as HTMLTextAreaElement + ).value = transaction.transactionNote ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyTransactionEdit--transactionDateString' + ) as HTMLInputElement + ).value = transaction.transactionDateString ?? '' + ;( + modalElement.querySelector( + '#lotOccupancyTransactionEdit--transactionTimeString' + ) as HTMLInputElement + ).value = transaction.transactionTimeString ?? '' + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped() + + los.initializeDatePickers(modalElement) + ;( + modalElement.querySelector( + '#lotOccupancyTransactionEdit--transactionAmount' + ) as HTMLInputElement + ).focus() + + modalElement + .querySelector('form') + ?.addEventListener('submit', doEdit) + + editCloseModalFunction = closeModalFunction + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + } + }) + } + + function deleteLotOccupancyTransaction(clickEvent: Event): void { + const transactionIndex = ( + (clickEvent.currentTarget as HTMLElement).closest( + '.container--lotOccupancyTransaction' + ) as HTMLElement + ).dataset.transactionIndex + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doDeleteLotOccupancyTransaction`, + { + lotOccupancyId, + transactionIndex + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + lotOccupancyTransactions: LotOccupancyTransaction[] + } + + if (responseJSON.success) { + lotOccupancyTransactions = responseJSON.lotOccupancyTransactions + renderLotOccupancyTransactions() + } else { + bulmaJS.alert({ + title: 'Error Deleting Transaction', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + bulmaJS.confirm({ + title: 'Delete Trasnaction', + message: 'Are you sure you want to delete this transaction?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Transaction', + callbackFunction: doDelete + } + }) + } + + function renderLotOccupancyTransactions(): void { + if (lotOccupancyTransactions.length === 0) { + // eslint-disable-next-line no-unsanitized/property + lotOccupancyTransactionsContainerElement.innerHTML = `
    +

    There are no transactions associated with this record.

    +
    ` + + return + } + + // eslint-disable-next-line no-unsanitized/property + lotOccupancyTransactionsContainerElement.innerHTML = ` + + + + + + + + + + + + +
    Date${los.escapedAliases.ExternalReceiptNumber}AmountOptions
    Transaction Total
    ` + + let transactionGrandTotal = 0 + + for (const lotOccupancyTransaction of lotOccupancyTransactions) { + transactionGrandTotal += lotOccupancyTransaction.transactionAmount + + const tableRowElement = document.createElement('tr') + tableRowElement.className = 'container--lotOccupancyTransaction' + tableRowElement.dataset.transactionIndex = + lotOccupancyTransaction.transactionIndex?.toString() + + let externalReceiptNumberHTML = '' + + if (lotOccupancyTransaction.externalReceiptNumber !== '') { + externalReceiptNumberHTML = cityssm.escapeHTML( + lotOccupancyTransaction.externalReceiptNumber ?? '' + ) + + if (los.dynamicsGPIntegrationIsEnabled) { + if (lotOccupancyTransaction.dynamicsGPDocument === undefined) { + externalReceiptNumberHTML += ` + + ` + } else if ( + lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed( + 2 + ) === lotOccupancyTransaction.transactionAmount.toFixed(2) + ) { + externalReceiptNumberHTML += ` + + ` + } else { + externalReceiptNumberHTML += ` + + ` + } + } + + externalReceiptNumberHTML += '
    ' + } + + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` + ${cityssm.escapeHTML(lotOccupancyTransaction.transactionDateString ?? '')} + + + ${externalReceiptNumberHTML} + ${cityssm.escapeHTML(lotOccupancyTransaction.transactionNote ?? '')} + + + $${cityssm.escapeHTML(lotOccupancyTransaction.transactionAmount.toFixed(2))} + + +
    + + +
    + ` + + tableRowElement + .querySelector('.button--edit') + ?.addEventListener('click', editLotOccupancyTransaction) + + tableRowElement + .querySelector('.button--delete') + ?.addEventListener('click', deleteLotOccupancyTransaction) + + lotOccupancyTransactionsContainerElement + .querySelector('tbody') + ?.append(tableRowElement) + } + + ;( + lotOccupancyTransactionsContainerElement.querySelector( + '#lotOccupancyTransactions--grandTotal' + ) as HTMLElement + ).textContent = `$${transactionGrandTotal.toFixed(2)}` + + const feeGrandTotal = getFeeGrandTotal() + + if (feeGrandTotal.toFixed(2) !== transactionGrandTotal.toFixed(2)) { + lotOccupancyTransactionsContainerElement.insertAdjacentHTML( + 'afterbegin', + `
    +
    +
    +
    +
    Outstanding Balance
    +
    +
    +
    + $${cityssm.escapeHTML((feeGrandTotal - transactionGrandTotal).toFixed(2))} +
    +
    +
    +
    ` + ) + } + } + + const addTransactionButtonElement = document.querySelector( + '#button--addTransaction' + ) as HTMLButtonElement + + addTransactionButtonElement.addEventListener('click', () => { + let transactionAmountElement: HTMLInputElement + let externalReceiptNumberElement: HTMLInputElement + + let addCloseModalFunction: () => void + + function doAddTransaction(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doAddLotOccupancyTransaction`, + submitEvent.currentTarget, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + lotOccupancyTransactions: LotOccupancyTransaction[] + } + + if (responseJSON.success) { + lotOccupancyTransactions = responseJSON.lotOccupancyTransactions + addCloseModalFunction() + renderLotOccupancyTransactions() + } else { + bulmaJS.confirm({ + title: 'Error Adding Transaction', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + // eslint-disable-next-line @typescript-eslint/naming-convention + function dynamicsGP_refreshExternalReceiptNumberIcon(): void { + const externalReceiptNumber = externalReceiptNumberElement.value + + const iconElement = externalReceiptNumberElement + .closest('.control') + ?.querySelector('.icon') as HTMLElement + + const helpTextElement = externalReceiptNumberElement + .closest('.field') + ?.querySelector('.help') as HTMLElement + + if (externalReceiptNumber === '') { + helpTextElement.innerHTML = ' ' + iconElement.innerHTML = + '' + return + } + + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doGetDynamicsGPDocument`, + { + externalReceiptNumber + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + dynamicsGPDocument?: DynamicsGPDocument + } + + if ( + !responseJSON.success || + responseJSON.dynamicsGPDocument === undefined + ) { + helpTextElement.textContent = 'No Matching Document Found' + iconElement.innerHTML = + '' + } else if ( + transactionAmountElement.valueAsNumber === + responseJSON.dynamicsGPDocument.documentTotal + ) { + helpTextElement.textContent = 'Matching Document Found' + iconElement.innerHTML = + '' + } else { + helpTextElement.textContent = `Matching Document: $${responseJSON.dynamicsGPDocument.documentTotal.toFixed(2)}` + iconElement.innerHTML = + '' + } + } + ) + } + + cityssm.openHtmlModal('lotOccupancy-addTransaction', { + onshow(modalElement) { + los.populateAliases(modalElement) + ;( + modalElement.querySelector( + '#lotOccupancyTransactionAdd--lotOccupancyId' + ) as HTMLInputElement + ).value = lotOccupancyId.toString() + + const feeGrandTotal = getFeeGrandTotal() + const transactionGrandTotal = getTransactionGrandTotal() + + transactionAmountElement = modalElement.querySelector( + '#lotOccupancyTransactionAdd--transactionAmount' + ) as HTMLInputElement + + transactionAmountElement.min = (-1 * transactionGrandTotal).toFixed( + 2 + ) + + transactionAmountElement.max = Math.max( + feeGrandTotal - transactionGrandTotal, + 0 + ).toFixed(2) + + transactionAmountElement.value = Math.max( + feeGrandTotal - transactionGrandTotal, + 0 + ).toFixed(2) + + if (los.dynamicsGPIntegrationIsEnabled) { + externalReceiptNumberElement = modalElement.querySelector( + // eslint-disable-next-line no-secrets/no-secrets + '#lotOccupancyTransactionAdd--externalReceiptNumber' + ) as HTMLInputElement + + const externalReceiptNumberControlElement = + externalReceiptNumberElement.closest('.control') as HTMLElement + + externalReceiptNumberControlElement.classList.add( + 'has-icons-right' + ) + + externalReceiptNumberControlElement.insertAdjacentHTML( + 'beforeend', + '' + ) + + externalReceiptNumberControlElement.insertAdjacentHTML( + 'afterend', + '

    ' + ) + + externalReceiptNumberElement.addEventListener( + 'change', + dynamicsGP_refreshExternalReceiptNumberIcon + ) + + transactionAmountElement.addEventListener( + 'change', + dynamicsGP_refreshExternalReceiptNumberIcon + ) + + dynamicsGP_refreshExternalReceiptNumberIcon() + } + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped() + + transactionAmountElement.focus() + + addCloseModalFunction = closeModalFunction + + modalElement + .querySelector('form') + ?.addEventListener('submit', doAddTransaction) + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + addTransactionButtonElement.focus() + } + }) + }) + + renderLotOccupancyFees() + })() + } +})() diff --git a/public-typescript/lotOccupancySearch.d.ts b/public/javascripts/lotOccupancySearch.d.ts similarity index 100% rename from public-typescript/lotOccupancySearch.d.ts rename to public/javascripts/lotOccupancySearch.d.ts diff --git a/public-typescript/lotOccupancySearch.js b/public/javascripts/lotOccupancySearch.js similarity index 100% rename from public-typescript/lotOccupancySearch.js rename to public/javascripts/lotOccupancySearch.js diff --git a/public/javascripts/lotOccupancySearch.min.js b/public/javascripts/lotOccupancySearch.min.js deleted file mode 100644 index 2012fb23..00000000 --- a/public/javascripts/lotOccupancySearch.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const a=exports.los,t=document.querySelector("#form--searchFilters"),e=document.querySelector("#container--searchResults"),s=Number.parseInt(document.querySelector("#searchFilter--limit").value,10),n=document.querySelector("#searchFilter--offset");function c(t){var n,c,l,i,d,u,p,h,y,f,v,$,m,g,L,S,b,O;const T=t;if(0===T.lotOccupancies.length)return void(e.innerHTML=`
    \n

    \n There are no ${a.escapedAliases.occupancy} records that meet the search criteria.\n

    \n
    `);const A=document.createElement("tbody"),M=cityssm.dateToString(new Date);for(const t of T.lotOccupancies){let e="";e=t.occupancyStartDateString<=M&&(""===t.occupancyEndDateString||t.occupancyEndDateString>=M)?`\n \n `:t.occupancyStartDateString>M?`\n \n `:`\n \n `;let s="";for(const a of null!==(n=t.lotOccupancyOccupants)&&void 0!==n?n:[])s+=`
  • \n \n \n \n ${cityssm.escapeHTML(null!==(d=a.occupantName)&&void 0!==d?d:"")}\n ${cityssm.escapeHTML(null!==(u=a.occupantFamilyName)&&void 0!==u?u:"")}\n
  • `;const o=(null!==(h=null===(p=t.lotOccupancyFees)||void 0===p?void 0:p.reduce((a,t)=>{var e,s,n;return a+((null!==(e=t.feeAmount)&&void 0!==e?e:0)+(null!==(s=t.taxAmount)&&void 0!==s?s:0))*(null!==(n=t.quantity)&&void 0!==n?n:0)},0))&&void 0!==h?h:0).toFixed(2),r=(null!==(f=null===(y=t.lotOccupancyTransactions)||void 0===y?void 0:y.reduce((a,t)=>a+t.transactionAmount,0))&&void 0!==f?f:0).toFixed(2);let S="";"0.00"===o&&"0.00"===r||(S=`\n \n `),A.insertAdjacentHTML("beforeend",`\n \n ${e}\n \n \n ${cityssm.escapeHTML(null!==(v=t.occupancyType)&&void 0!==v?v:"")}\n
    \n #${t.lotOccupancyId}\n \n ${-1===(null!==($=t.lotId)&&void 0!==$?$:-1)?`(No ${a.escapedAliases.Lot})`:`${cityssm.escapeHTML(null!==(g=t.lotName)&&void 0!==g?g:"")}`}
    \n ${cityssm.escapeHTML(null!==(L=t.mapName)&&void 0!==L?L:"")}\n \n ${t.occupancyStartDateString}\n \n ${t.occupancyEndDate?t.occupancyEndDateString:'(No End Date)'}\n \n ${""===s?"":`
      ${s}
    `}\n \n ${S}\n \n ${t.printEJS?`\n \n `:""}`)}e.innerHTML=`\n \n \n \n \n \n \n \n \n \n \n
    ${a.escapedAliases.Occupancy} Type${a.escapedAliases.Lot}${a.escapedAliases.OccupancyStartDate}End Date${a.escapedAliases.Occupants}Fees and TransactionsPrint
    `,null===(S=e.querySelector("table"))||void 0===S||S.append(A),e.insertAdjacentHTML("beforeend",a.getSearchResultsPagerHTML(s,T.offset,T.count)),null===(b=e.querySelector("button[data-page='previous']"))||void 0===b||b.addEventListener("click",o),null===(O=e.querySelector("button[data-page='next']"))||void 0===O||O.addEventListener("click",r)}function l(){e.innerHTML=a.getLoadingParagraphHTML(`Loading ${a.escapedAliases.Occupancies}...`),cityssm.postJSON(`${a.urlPrefix}/lotOccupancies/doSearchLotOccupancies`,t,c)}function i(){n.value="0",l()}function o(){n.value=Math.max(Number.parseInt(n.value,10)-s,0).toString(),l()}function r(){n.value=(Number.parseInt(n.value,10)+s).toString(),l()}const d=t.querySelectorAll("input, select");for(const a of d)a.addEventListener("change",i);t.addEventListener("submit",a=>{a.preventDefault()}),l()})(); \ No newline at end of file diff --git a/public-typescript/lotOccupancySearch.ts b/public/javascripts/lotOccupancySearch.ts similarity index 98% rename from public-typescript/lotOccupancySearch.ts rename to public/javascripts/lotOccupancySearch.ts index 7aecda2f..d66489da 100644 --- a/public-typescript/lotOccupancySearch.ts +++ b/public/javascripts/lotOccupancySearch.ts @@ -3,8 +3,8 @@ import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' -import type { LOS } from '../types/globalTypes.js' -import type { LotOccupancy } from '../types/recordTypes.js' +import type { LOS } from '../../types/globalTypes.js' +import type { LotOccupancy } from '../../types/recordTypes.js' declare const cityssm: cityssmGlobal diff --git a/public-typescript/lotSearch.d.ts b/public/javascripts/lotSearch.d.ts similarity index 100% rename from public-typescript/lotSearch.d.ts rename to public/javascripts/lotSearch.d.ts diff --git a/public-typescript/lotSearch.js b/public/javascripts/lotSearch.js similarity index 100% rename from public-typescript/lotSearch.js rename to public/javascripts/lotSearch.js diff --git a/public/javascripts/lotSearch.min.js b/public/javascripts/lotSearch.min.js deleted file mode 100644 index 27f5f72e..00000000 --- a/public/javascripts/lotSearch.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=document.querySelector("#form--searchFilters"),s=document.querySelector("#container--searchResults"),a=Number.parseInt(document.querySelector("#searchFilter--limit").value,10),n=document.querySelector("#searchFilter--offset");function r(t){var n,r,o,l,d,u,p;const h=t;if(0===h.lots.length)return void(s.innerHTML=`
    \n

    There are no ${e.escapedAliases.lots} that meet the search criteria.

    \n
    `);const m=document.createElement("tbody");for(const t of h.lots)m.insertAdjacentHTML("beforeend",`\n \n `);s.innerHTML=`
    \n \n ${cityssm.escapeHTML(null!==(n=t.lotName)&&void 0!==n?n:"")}\n \n \n \n ${t.mapName?cityssm.escapeHTML(t.mapName):'(No Name)'}\n \n \n ${cityssm.escapeHTML(null!==(r=t.lotType)&&void 0!==r?r:"")}\n \n ${t.lotStatusId?cityssm.escapeHTML(null!==(o=t.lotStatus)&&void 0!==o?o:""):'(No Status)'}
    \n ${(null!==(l=t.lotOccupancyCount)&&void 0!==l?l:0)>0?'Currently Occupied':""}\n
    \n \n \n \n \n \n \n
    ${e.escapedAliases.Lot}${e.escapedAliases.Map}${e.escapedAliases.Lot} TypeStatus
    `,s.insertAdjacentHTML("beforeend",e.getSearchResultsPagerHTML(a,h.offset,h.count)),null===(d=s.querySelector("table"))||void 0===d||d.append(m),null===(u=s.querySelector("button[data-page='previous']"))||void 0===u||u.addEventListener("click",c),null===(p=s.querySelector("button[data-page='next']"))||void 0===p||p.addEventListener("click",i)}function o(){s.innerHTML=e.getLoadingParagraphHTML(`Loading ${e.escapedAliases.Lots}...`),cityssm.postJSON(`${e.urlPrefix}/lots/doSearchLots`,t,r)}function l(){n.value="0",o()}function c(){n.value=Math.max(Number.parseInt(n.value,10)-a,0).toString(),o()}function i(){n.value=(Number.parseInt(n.value,10)+a).toString(),o()}const d=t.querySelectorAll("input, select");for(const e of d)e.addEventListener("change",l);t.addEventListener("submit",e=>{e.preventDefault()}),o()})(); \ No newline at end of file diff --git a/public-typescript/lotSearch.ts b/public/javascripts/lotSearch.ts similarity index 97% rename from public-typescript/lotSearch.ts rename to public/javascripts/lotSearch.ts index 872a8710..33c403e5 100644 --- a/public-typescript/lotSearch.ts +++ b/public/javascripts/lotSearch.ts @@ -3,8 +3,8 @@ import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' -import type { LOS } from '../types/globalTypes.js' -import type { Lot } from '../types/recordTypes.js' +import type { LOS } from '../../types/globalTypes.js' +import type { Lot } from '../../types/recordTypes.js' declare const cityssm: cityssmGlobal diff --git a/public-typescript/lotView.d.ts b/public/javascripts/lotView.d.ts similarity index 100% rename from public-typescript/lotView.d.ts rename to public/javascripts/lotView.d.ts diff --git a/public-typescript/lotView.js b/public/javascripts/lotView.js similarity index 100% rename from public-typescript/lotView.js rename to public/javascripts/lotView.js diff --git a/public/javascripts/lotView.min.js b/public/javascripts/lotView.min.js deleted file mode 100644 index 46de10bf..00000000 --- a/public/javascripts/lotView.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e;const t=document.querySelector("#lot--map");null!==t&&exports.los.highlightMap(t,null!==(e=t.dataset.mapKey)&&void 0!==e?e:"","success")})(); \ No newline at end of file diff --git a/public-typescript/lotView.ts b/public/javascripts/lotView.ts similarity index 89% rename from public-typescript/lotView.ts rename to public/javascripts/lotView.ts index f027e209..a9e1474c 100644 --- a/public-typescript/lotView.ts +++ b/public/javascripts/lotView.ts @@ -1,7 +1,7 @@ // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair /* eslint-disable unicorn/prefer-module */ -import type { LOS } from '../types/globalTypes.js' +import type { LOS } from '../../types/globalTypes.js' declare const exports: Record ;(() => { diff --git a/public-typescript/main.d.ts b/public/javascripts/main.d.ts similarity index 100% rename from public-typescript/main.d.ts rename to public/javascripts/main.d.ts diff --git a/public-typescript/main.js b/public/javascripts/main.js similarity index 100% rename from public-typescript/main.js rename to public/javascripts/main.js diff --git a/public/javascripts/main.min.js b/public/javascripts/main.min.js deleted file mode 100644 index f1fe7db0..00000000 --- a/public/javascripts/main.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e,t,s,a;let o=!1;function n(){return o}function i(e){const t=e.currentTarget.closest(".field").querySelector("input, select");if(t.classList.remove("is-readonly"),"INPUT"===t.tagName)t.readOnly=!1,t.disabled=!1;else{const e=t.querySelectorAll("option");for(const t of e)t.disabled=!1}t.focus()}const c={type:"date",dateFormat:"yyyy-MM-dd",showFooter:!1,color:"info",displayMode:"dialog"};const r=Object.freeze({Map:cityssm.escapeHTML(exports.aliases.map),map:cityssm.escapeHTML(exports.aliases.map.toLowerCase()),Maps:cityssm.escapeHTML(exports.aliases.maps),maps:cityssm.escapeHTML(exports.aliases.maps.toLowerCase()),Lot:cityssm.escapeHTML(exports.aliases.lot),lot:cityssm.escapeHTML(exports.aliases.lot.toLowerCase()),Lots:cityssm.escapeHTML(exports.aliases.lots),lots:cityssm.escapeHTML(exports.aliases.lots.toLowerCase()),Occupancy:cityssm.escapeHTML(exports.aliases.occupancy),occupancy:cityssm.escapeHTML(exports.aliases.occupancy.toLowerCase()),Occupancies:cityssm.escapeHTML(exports.aliases.occupancies),occupancies:cityssm.escapeHTML(exports.aliases.occupancies.toLowerCase()),Occupant:cityssm.escapeHTML(exports.aliases.occupant),occupant:cityssm.escapeHTML(exports.aliases.occupant.toLowerCase()),Occupants:cityssm.escapeHTML(exports.aliases.occupants),occupants:cityssm.escapeHTML(exports.aliases.occupants.toLowerCase()),ExternalReceiptNumber:cityssm.escapeHTML(exports.aliases.externalReceiptNumber),externalReceiptNumber:cityssm.escapeHTML(exports.aliases.externalReceiptNumber.toLowerCase()),OccupancyStartDate:cityssm.escapeHTML(exports.aliases.occupancyStartDate),occupancyStartDate:cityssm.escapeHTML(exports.aliases.occupancyStartDate.toLowerCase()),WorkOrderOpenDate:cityssm.escapeHTML(exports.aliases.workOrderOpenDate),workOrderOpenDate:cityssm.escapeHTML(exports.aliases.workOrderOpenDate.toLowerCase()),WorkOrderCloseDate:cityssm.escapeHTML(exports.aliases.workOrderCloseDate),workOrderCloseDate:cityssm.escapeHTML(exports.aliases.workOrderCloseDate.toLowerCase())}),l=["red","green","orange","blue","pink","yellow","purple"],p=["bright","light","dark"];const u=null!==(t=null===(e=document.querySelector("main"))||void 0===e?void 0:e.dataset.urlPrefix)&&void 0!==t?t:"";function d(e,t,s,a){return u+"/"+e+(t?`/${t.toString()}`:"")+(t&&s?"/edit":"")+(a?`/?t=${Date.now().toString()}`:"")}const y=exports.dynamicsGPIntegrationIsEnabled,m={urlPrefix:u,apiKey:null!==(a=null===(s=document.querySelector("main"))||void 0===s?void 0:s.dataset.apiKey)&&void 0!==a?a:"",dynamicsGPIntegrationIsEnabled:y,highlightMap:function(e,t,s){let a,o=t;for(;null===(a=e.querySelector(`#${o}`))&&o.includes("-");)o=o.slice(0,Math.max(0,o.lastIndexOf("-")));if(null!==a){a.style.fill="",a.classList.add("highlight",`is-${s}`);const e=a.querySelectorAll("path");for(const t of e)t.style.fill=""}},initializeUnlockFieldButtons:function(e){const t=e.querySelectorAll(".is-unlock-field-button");for(const e of t)e.addEventListener("click",i)},initializeDatePickers:function(e){var t,s,a;const o=e.querySelectorAll("input[type='date']");for(const n of o){const o=Object.assign({},c);n.required&&(o.showClearButton=!1),""!==n.min&&(o.minDate=cityssm.dateStringToDate(n.min)),""!==n.max&&(o.maxDate=cityssm.dateStringToDate(n.max));const i=exports.bulmaCalendar.attach(n,o)[0];i.on("save",()=>{n.value=i.value(),n.dispatchEvent(new Event("change"))}),i.on("show",()=>{var e;null===(e=document.querySelector("html"))||void 0===e||e.classList.add("is-clipped")}),i.on("hide",()=>{bulmaJS.toggleHtmlClipped()});const r=e.querySelector(`#${i._id}`),l=r.querySelectorAll(".datepicker-nav button.is-text");for(const e of l)e.classList.add(`is-${null!==(t=c.color)&&void 0!==t?t:""}`),e.classList.remove("is-text");const p=r.querySelector(".datetimepicker-clear-button");null!==p&&(n.required?p.remove():(p.dataset.tooltip="Clear",p.setAttribute("aria-label","Clear"),p.innerHTML=''));const u=document.querySelector(`label[for='${n.id}']`);null!==u&&(null===(s=r.querySelector(".datetimepicker-dummy-input"))||void 0===s||s.setAttribute("aria-label",null!==(a=u.textContent)&&void 0!==a?a:""))}},populateAliases:function(e){const t=e.querySelectorAll(".alias");for(const e of t)switch(e.dataset.alias){case"Map":e.textContent=exports.aliases.map;break;case"Lot":e.textContent=exports.aliases.lot;break;case"lot":e.textContent=exports.aliases.lot.toLowerCase();break;case"Occupancy":e.textContent=exports.aliases.occupancy;break;case"occupancy":e.textContent=exports.aliases.occupancy.toLowerCase();break;case"Occupant":e.textContent=exports.aliases.occupant;break;case"occupant":e.textContent=exports.aliases.occupant.toLowerCase();break;case"ExternalReceiptNumber":e.textContent=exports.aliases.externalReceiptNumber}},escapedAliases:r,getRandomColor:function(e){let t=e;return t.length<2&&(t+="a1"),exports.randomColor({seed:t+t,hue:l[t.codePointAt(t.length-1)%l.length],luminosity:p[t.codePointAt(t.length-2)%p.length]})},setUnsavedChanges:function(){n()||(o=!0,cityssm.enableNavBlocker())},clearUnsavedChanges:function(){o=!1,cityssm.disableNavBlocker()},hasUnsavedChanges:n,getMoveUpDownButtonFieldHTML:function(e,t,s=!0){return`
    \n
    \n \n \n \n
    \n
    \n \n \n \n
    \n
    `},getLoadingParagraphHTML:function(e="Loading..."){return`

    \n
    \n ${cityssm.escapeHTML(e)}\n

    `},getSearchResultsPagerHTML:function(e,t,s){return`
    \n
    \n
    \n Displaying\n ${(t+1).toString()}\n to\n ${Math.min(s,e+t).toString()}\n of\n ${s.toString()}\n
    \n
    \n
    \n ${t>0?'
    \n \n
    ':""}\n ${e+t\n \n
    ':""}\n
    \n `},getMapURL:function(e="",t=!1,s=!1){return d("maps",e,t,s)},getLotURL:function(e="",t=!1,s=!1){return d("lots",e,t,s)},getLotOccupancyURL:function(e="",t=!1,s=!1){return d("lotOccupancies",e,t,s)},getWorkOrderURL:function(e="",t=!1,s=!1){return d("workOrders",e,t,s)}};exports.los=m})(); \ No newline at end of file diff --git a/public-typescript/main.ts b/public/javascripts/main.ts similarity index 99% rename from public-typescript/main.ts rename to public/javascripts/main.ts index 266869b7..eaa315d4 100644 --- a/public-typescript/main.ts +++ b/public/javascripts/main.ts @@ -5,7 +5,7 @@ import type { BulmaJS } from '@cityssm/bulma-js/types.js' import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' import type { Options as BulmaCalendarOptions } from 'bulma-calendar' -import type { LOS } from '../types/globalTypes.js' +import type { LOS } from '../../types/globalTypes.js' type RandomColorHue = | 'red' diff --git a/public-typescript/mapEdit.d.ts b/public/javascripts/mapEdit.d.ts similarity index 100% rename from public-typescript/mapEdit.d.ts rename to public/javascripts/mapEdit.d.ts diff --git a/public-typescript/mapEdit.js b/public/javascripts/mapEdit.js similarity index 100% rename from public-typescript/mapEdit.js rename to public/javascripts/mapEdit.js diff --git a/public/javascripts/mapEdit.min.js b/public/javascripts/mapEdit.min.js deleted file mode 100644 index 848d9507..00000000 --- a/public/javascripts/mapEdit.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e;const t=exports.los,a=document.querySelector("#map--mapId").value,s=""===a,o=document.querySelector("#form--map");function l(){var e;t.setUnsavedChanges(),null===(e=document.querySelector("button[type='submit'][form='form--map']"))||void 0===e||e.classList.remove("is-light")}o.addEventListener("submit",function(e){e.preventDefault(),cityssm.postJSON(`${t.urlPrefix}/maps/${s?"doCreateMap":"doUpdateMap"}`,o,e=>{var a;const o=e;o.success?(function(){var e;t.clearUnsavedChanges(),null===(e=document.querySelector("button[type='submit'][form='form--map']"))||void 0===e||e.classList.add("is-light")}(),s?window.location.href=t.getMapURL(o.mapId,!0):bulmaJS.alert({message:`${t.escapedAliases.Map} Updated Successfully`,contextualColorName:"success"})):bulmaJS.alert({title:`Error Updating ${t.escapedAliases.Map}`,message:null!==(a=o.errorMessage)&&void 0!==a?a:"",contextualColorName:"danger"})})});const r=o.querySelectorAll("input, select");for(const e of r)e.addEventListener("change",l);null===(e=document.querySelector("#button--deleteMap"))||void 0===e||e.addEventListener("click",e=>{e.preventDefault(),bulmaJS.confirm({title:`Delete ${t.escapedAliases.Map}`,message:`Are you sure you want to delete this ${t.escapedAliases.map} and all related ${t.escapedAliases.lots}?`,contextualColorName:"warning",okButton:{text:`Yes, Delete ${t.escapedAliases.Map}`,callbackFunction:function(){cityssm.postJSON(`${t.urlPrefix}/maps/doDeleteMap`,{mapId:a},e=>{var a;const s=e;s.success?window.location.href=t.getMapURL():bulmaJS.alert({title:`Error Deleting ${t.escapedAliases.Map}`,message:null!==(a=s.errorMessage)&&void 0!==a?a:"",contextualColorName:"danger"})})}}})})})(); \ No newline at end of file diff --git a/public-typescript/mapEdit.ts b/public/javascripts/mapEdit.ts similarity index 98% rename from public-typescript/mapEdit.ts rename to public/javascripts/mapEdit.ts index 119069c4..0573282b 100644 --- a/public-typescript/mapEdit.ts +++ b/public/javascripts/mapEdit.ts @@ -4,7 +4,7 @@ import type { BulmaJS } from '@cityssm/bulma-js/types.js' import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' -import type { LOS } from '../types/globalTypes.js' +import type { LOS } from '../../types/globalTypes.js' declare const cityssm: cityssmGlobal declare const bulmaJS: BulmaJS diff --git a/public-typescript/mapSearch.d.ts b/public/javascripts/mapSearch.d.ts similarity index 100% rename from public-typescript/mapSearch.d.ts rename to public/javascripts/mapSearch.d.ts diff --git a/public-typescript/mapSearch.js b/public/javascripts/mapSearch.js similarity index 100% rename from public-typescript/mapSearch.js rename to public/javascripts/mapSearch.js diff --git a/public/javascripts/mapSearch.min.js b/public/javascripts/mapSearch.min.js deleted file mode 100644 index 45c3788f..00000000 --- a/public/javascripts/mapSearch.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e;const a=exports.los,s=exports.maps,t=document.querySelector("#searchFilter--map"),n=document.querySelector("#container--searchResults");function i(){var e,i,d,l,r,o,c,p,m,u,h,v,$,L,f,b,y;n.innerHTML=a.getLoadingParagraphHTML(`Loading ${a.escapedAliases.Maps}...`);let H=0;const M=document.createElement("tbody"),g=t.value.trim().toLowerCase().split(" ");for(const t of s){const s=`${null!==(e=t.mapName)&&void 0!==e?e:""} ${null!==(i=t.mapDescription)&&void 0!==i?i:""} ${null!==(d=t.mapAddress1)&&void 0!==d?d:""} ${null!==(l=t.mapAddress2)&&void 0!==l?l:""}`.toLowerCase();let n=!0;for(const e of g)if(!s.includes(e)){n=!1;break}n&&(H+=1,M.insertAdjacentHTML("beforeend",`
    \n \n `))}if(n.innerHTML="",0===H)n.innerHTML=`
    \n

    There are no ${a.escapedAliases.maps} that meet the search criteria.

    \n
    `;else{const e=document.createElement("table");e.className="table is-fullwidth is-striped is-hoverable has-sticky-header",e.innerHTML=`\n \n \n \n \n \n \n `,e.append(M),n.append(e)}}t.addEventListener("keyup",i),null===(e=document.querySelector("#form--searchFilters"))||void 0===e||e.addEventListener("submit",e=>{e.preventDefault(),i()}),i()})(); \ No newline at end of file diff --git a/public-typescript/mapSearch.ts b/public/javascripts/mapSearch.ts similarity index 97% rename from public-typescript/mapSearch.ts rename to public/javascripts/mapSearch.ts index 684a1d9e..1c7f09e2 100644 --- a/public-typescript/mapSearch.ts +++ b/public/javascripts/mapSearch.ts @@ -3,8 +3,8 @@ import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' -import type { LOS } from '../types/globalTypes.js' -import type { MapRecord } from '../types/recordTypes.js' +import type { LOS } from '../../types/globalTypes.js' +import type { MapRecord } from '../../types/recordTypes.js' declare const cityssm: cityssmGlobal diff --git a/public-typescript/mapView.d.ts b/public/javascripts/mapView.d.ts similarity index 100% rename from public-typescript/mapView.d.ts rename to public/javascripts/mapView.d.ts diff --git a/public-typescript/mapView.js b/public/javascripts/mapView.js similarity index 100% rename from public-typescript/mapView.js rename to public/javascripts/mapView.js diff --git a/public/javascripts/mapView.min.js b/public/javascripts/mapView.min.js deleted file mode 100644 index 1c809bc7..00000000 --- a/public/javascripts/mapView.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e,t;const a=document.querySelector("#map--leaflet");if(null!==a){const o=[Number.parseFloat(null!==(e=a.dataset.mapLatitude)&&void 0!==e?e:""),Number.parseFloat(null!==(t=a.dataset.mapLongitude)&&void 0!==t?t:"")],r=L.map(a);r.setView(o,15),L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",{maxZoom:19,attribution:"© OpenStreetMap"}).addTo(r),L.marker(o).addTo(r)}})(); \ No newline at end of file diff --git a/public-typescript/mapView.ts b/public/javascripts/mapView.ts similarity index 100% rename from public-typescript/mapView.ts rename to public/javascripts/mapView.ts diff --git a/public-typescript/reportSearch.d.ts b/public/javascripts/reportSearch.d.ts similarity index 100% rename from public-typescript/reportSearch.d.ts rename to public/javascripts/reportSearch.d.ts diff --git a/public-typescript/reportSearch.js b/public/javascripts/reportSearch.js similarity index 100% rename from public-typescript/reportSearch.js rename to public/javascripts/reportSearch.js diff --git a/public/javascripts/reportSearch.min.js b/public/javascripts/reportSearch.min.js deleted file mode 100644 index 70bfe252..00000000 --- a/public/javascripts/reportSearch.min.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{const e=document.querySelectorAll(".menu a"),t=document.querySelectorAll(".tabs-container > div");function s(s){s.preventDefault();for(const t of e)t.classList.remove("is-active");const c=s.currentTarget;c.classList.add("is-active");const i=c.href.slice(Math.max(0,c.href.indexOf("#")+1));for(const e of t)e.id===i?e.classList.remove("is-hidden"):e.classList.add("is-hidden")}for(const t of e)t.addEventListener("click",s)})(); \ No newline at end of file diff --git a/public-typescript/reportSearch.ts b/public/javascripts/reportSearch.ts similarity index 100% rename from public-typescript/reportSearch.ts rename to public/javascripts/reportSearch.ts diff --git a/public-typescript/workOrderEdit/workOrderEdit.d.ts b/public/javascripts/workOrderEdit.d.ts similarity index 100% rename from public-typescript/workOrderEdit/workOrderEdit.d.ts rename to public/javascripts/workOrderEdit.d.ts diff --git a/public/javascripts/workOrderEdit.js b/public/javascripts/workOrderEdit.js new file mode 100644 index 00000000..fa084417 --- /dev/null +++ b/public/javascripts/workOrderEdit.js @@ -0,0 +1,1257 @@ +"use strict"; +// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair +/* eslint-disable unicorn/prefer-module */ +Object.defineProperty(exports, "__esModule", { value: true }); +(() => { + const los = exports.los; + const workOrderId = document.querySelector('#workOrderEdit--workOrderId').value; + const isCreate = workOrderId === ''; + const workOrderFormElement = document.querySelector('#form--workOrderEdit'); + los.initializeDatePickers(workOrderFormElement + .querySelector('#workOrderEdit--workOrderOpenDateString') + ?.closest('.field')); + los.initializeUnlockFieldButtons(workOrderFormElement); + function setUnsavedChanges() { + los.setUnsavedChanges(); + document + .querySelector("button[type='submit'][form='form--workOrderEdit']") + ?.classList.remove('is-light'); + } + function clearUnsavedChanges() { + los.clearUnsavedChanges(); + document + .querySelector("button[type='submit'][form='form--workOrderEdit']") + ?.classList.add('is-light'); + } + workOrderFormElement.addEventListener('submit', (submitEvent) => { + submitEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/workOrders/${isCreate ? 'doCreateWorkOrder' : 'doUpdateWorkOrder'}`, submitEvent.currentTarget, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + clearUnsavedChanges(); + if (isCreate) { + window.location.href = los.getWorkOrderURL(responseJSON.workOrderId, true); + } + else { + bulmaJS.alert({ + message: 'Work Order Updated Successfully', + contextualColorName: 'success' + }); + } + } + else { + bulmaJS.alert({ + title: 'Error Updating Work Order', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + }); + const inputElements = workOrderFormElement.querySelectorAll('input, select, textarea'); + for (const inputElement of inputElements) { + inputElement.addEventListener('change', setUnsavedChanges); + } + /* + * Work Order Options + */ + function doClose() { + cityssm.postJSON(`${los.urlPrefix}/workOrders/doCloseWorkOrder`, { + workOrderId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + clearUnsavedChanges(); + window.location.href = los.getWorkOrderURL(workOrderId); + } + else { + bulmaJS.alert({ + title: 'Error Closing Work Order', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrder`, { + workOrderId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + clearUnsavedChanges(); + window.location.href = `${los.urlPrefix}/workOrders`; + } + else { + bulmaJS.alert({ + title: 'Error Deleting Work Order', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + let workOrderMilestones; + document + .querySelector('#button--closeWorkOrder') + ?.addEventListener('click', () => { + const hasOpenMilestones = workOrderMilestones.some((milestone) => { + return !milestone.workOrderMilestoneCompletionDate; + }); + if (hasOpenMilestones) { + bulmaJS.alert({ + title: 'Outstanding Milestones', + message: `You cannot close a work order with outstanding milestones. + Either complete the outstanding milestones, or remove them from the work order.`, + contextualColorName: 'warning' + }); + /* + // Disable closing work orders with open milestones + bulmaJS.confirm({ + title: "Close Work Order with Outstanding Milestones", + message: + "Are you sure you want to close this work order with outstanding milestones?", + contextualColorName: "danger", + okButton: { + text: "Yes, Close Work Order", + callbackFunction: doClose + } + }); + */ + } + else { + bulmaJS.confirm({ + title: 'Close Work Order', + message: los.hasUnsavedChanges() + ? 'Are you sure you want to close this work order with unsaved changes?' + : 'Are you sure you want to close this work order?', + contextualColorName: los.hasUnsavedChanges() ? 'warning' : 'info', + okButton: { + text: 'Yes, Close Work Order', + callbackFunction: doClose + } + }); + } + }); + document + .querySelector('#button--deleteWorkOrder') + ?.addEventListener('click', (clickEvent) => { + clickEvent.preventDefault(); + bulmaJS.confirm({ + title: 'Delete Work Order', + message: 'Are you sure you want to delete this work order?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Work Order', + callbackFunction: doDelete + } + }); + }); + /** + * Related Lots + */ + if (!isCreate) { + ; + (() => { + let workOrderLots = exports.workOrderLots; + delete exports.workOrderLots; + let workOrderLotOccupancies = exports.workOrderLotOccupancies; + delete exports.workOrderLotOccupancies; + function deleteLotOccupancy(clickEvent) { + const lotOccupancyId = clickEvent.currentTarget.closest('.container--lotOccupancy').dataset.lotOccupancyId; + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrderLotOccupancy`, { + workOrderId, + lotOccupancyId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderLotOccupancies = responseJSON.workOrderLotOccupancies; + renderRelatedLotsAndOccupancies(); + } + else { + bulmaJS.alert({ + title: 'Error Deleting Relationship', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + bulmaJS.confirm({ + title: `Delete ${los.escapedAliases.Occupancy} Relationship`, + message: `Are you sure you want to remove the relationship to this ${los.escapedAliases.occupancy} record from this work order? Note that the record will remain.`, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Relationship', + callbackFunction: doDelete + } + }); + } + function addLot(lotId, callbackFunction) { + cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderLot`, { + workOrderId, + lotId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderLots = responseJSON.workOrderLots; + renderRelatedLotsAndOccupancies(); + } + else { + bulmaJS.alert({ + title: `Error Adding ${los.escapedAliases.Lot}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + if (callbackFunction !== undefined) { + callbackFunction(responseJSON.success); + } + }); + } + function addLotOccupancy(lotOccupancyId, callbackFunction) { + cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderLotOccupancy`, { + workOrderId, + lotOccupancyId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderLotOccupancies = responseJSON.workOrderLotOccupancies; + renderRelatedLotsAndOccupancies(); + } + else { + bulmaJS.alert({ + title: `Error Adding ${los.escapedAliases.Occupancy}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + if (callbackFunction !== undefined) { + callbackFunction(responseJSON.success); + } + }); + } + function addLotFromLotOccupancy(clickEvent) { + const lotId = clickEvent.currentTarget.dataset.lotId ?? ''; + addLot(lotId); + } + function renderRelatedOccupancies() { + const occupanciesContainerElement = document.querySelector('#container--lotOccupancies'); + document.querySelector(".tabs a[href='#relatedTab--lotOccupancies'] .tag").textContent = workOrderLotOccupancies.length.toString(); + if (workOrderLotOccupancies.length === 0) { + // eslint-disable-next-line no-unsanitized/property + occupanciesContainerElement.innerHTML = `
    +

    There are no ${los.escapedAliases.occupancies} associated with this work order.

    +
    `; + return; + } + // eslint-disable-next-line no-unsanitized/property + occupanciesContainerElement.innerHTML = `
    \n \n ${cityssm.escapeHTML(""===(null!==(r=t.mapName)&&void 0!==r?r:"")?"(No Name)":null!==(o=t.mapName)&&void 0!==o?o:"")}\n
    \n \n ${cityssm.escapeHTML(null!==(c=t.mapDescription)&&void 0!==c?c:"")}\n \n
    \n ${""===(null!==(p=t.mapAddress1)&&void 0!==p?p:"")?"":`${cityssm.escapeHTML(null!==(m=t.mapAddress1)&&void 0!==m?m:"")}
    `}\n ${""===(null!==(u=t.mapAddress2)&&void 0!==u?u:"")?"":`${cityssm.escapeHTML(null!==(h=t.mapAddress2)&&void 0!==h?h:"")}
    `}\n ${t.mapCity||t.mapProvince?`${cityssm.escapeHTML(null!==(v=t.mapCity)&&void 0!==v?v:"")}, ${cityssm.escapeHTML(null!==($=t.mapProvince)&&void 0!==$?$:"")}
    `:""}\n ${""===(null!==(L=t.mapPostalCode)&&void 0!==L?L:"")?"":cityssm.escapeHTML(null!==(f=t.mapPostalCode)&&void 0!==f?f:"")}\n
    \n ${cityssm.escapeHTML(null!==(b=t.mapPhoneNumber)&&void 0!==b?b:"")}\n \n ${t.mapLatitude&&t.mapLongitude?'\n \n ':""}\n \n ${""===(null!==(y=t.mapSVG)&&void 0!==y?y:"")?"":''}\n \n ${t.lotCount}\n
    ${a.escapedAliases.Map}AddressPhone NumberCoordinatesImage${a.escapedAliases.Lot} Count
    + + + + + + + + + + +
    ${los.escapedAliases.Occupancy} Type${los.escapedAliases.Lot}${los.escapedAliases.OccupancyStartDate}End Date${los.escapedAliases.Occupants}
    `; + const currentDateString = cityssm.dateToString(new Date()); + for (const lotOccupancy of workOrderLotOccupancies) { + const rowElement = document.createElement('tr'); + rowElement.className = 'container--lotOccupancy'; + rowElement.dataset.lotOccupancyId = + lotOccupancy.lotOccupancyId.toString(); + const isActive = !(lotOccupancy.occupancyEndDate && + lotOccupancy.occupancyEndDateString < currentDateString); + const hasLotRecord = lotOccupancy.lotId && + workOrderLots.some((lot) => { + return lotOccupancy.lotId === lot.lotId; + }); + // eslint-disable-next-line no-unsanitized/property + rowElement.innerHTML = ` + ${isActive + ? `` + : ``} + + + ${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')} +
    + #${lotOccupancy.lotOccupancyId} + `; + if (lotOccupancy.lotId) { + // eslint-disable-next-line no-unsanitized/method + rowElement.insertAdjacentHTML('beforeend', ` + ${cityssm.escapeHTML(lotOccupancy.lotName ?? '')} + ${hasLotRecord + ? '' + : ` `} + `); + } + else { + // eslint-disable-next-line no-unsanitized/method + rowElement.insertAdjacentHTML('beforeend', `(No ${los.escapedAliases.Lot})`); + } + let occupantsHTML = ''; + for (const occupant of lotOccupancy.lotOccupancyOccupants) { + occupantsHTML += `
  • + + + + ${cityssm.escapeHTML(occupant.occupantName ?? '')} + ${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')} +
  • `; + } + // eslint-disable-next-line no-unsanitized/method + rowElement.insertAdjacentHTML('beforeend', ` + ${lotOccupancy.occupancyStartDateString} + + ${lotOccupancy.occupancyEndDate + ? lotOccupancy.occupancyEndDateString + : '(No End Date)'} + + ${lotOccupancy.lotOccupancyOccupants.length === 0 + ? `(No ${los.escapedAliases.Occupants})` + : `
      ${occupantsHTML}
    `} + + + `); + rowElement + .querySelector('.button--addLot') + ?.addEventListener('click', addLotFromLotOccupancy); + rowElement + .querySelector('.button--deleteLotOccupancy') + ?.addEventListener('click', deleteLotOccupancy); + occupanciesContainerElement.querySelector('tbody')?.append(rowElement); + } + } + function openEditLotStatus(clickEvent) { + const lotId = Number.parseInt(clickEvent.currentTarget.closest('.container--lot').dataset.lotId ?? '', 10); + const lot = workOrderLots.find((possibleLot) => { + return possibleLot.lotId === lotId; + }); + let editCloseModalFunction; + function doUpdateLotStatus(submitEvent) { + submitEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/workOrders/doUpdateLotStatus`, submitEvent.currentTarget, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderLots = responseJSON.workOrderLots; + renderRelatedLotsAndOccupancies(); + editCloseModalFunction(); + } + else { + bulmaJS.alert({ + title: 'Error Deleting Relationship', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + cityssm.openHtmlModal('lot-editLotStatus', { + onshow(modalElement) { + los.populateAliases(modalElement); + modalElement.querySelector('#lotStatusEdit--lotId').value = lotId.toString(); + modalElement.querySelector('#lotStatusEdit--lotName').value = lot.lotName ?? ''; + const lotStatusElement = modalElement.querySelector('#lotStatusEdit--lotStatusId'); + let lotStatusFound = false; + for (const lotStatus of exports.lotStatuses) { + const optionElement = document.createElement('option'); + optionElement.value = lotStatus.lotStatusId.toString(); + optionElement.textContent = lotStatus.lotStatus; + if (lotStatus.lotStatusId === lot.lotStatusId) { + lotStatusFound = true; + } + lotStatusElement.append(optionElement); + } + if (!lotStatusFound && lot.lotStatusId) { + const optionElement = document.createElement('option'); + optionElement.value = lot.lotStatusId.toString(); + optionElement.textContent = lot.lotStatus ?? ''; + lotStatusElement.append(optionElement); + } + if (lot.lotStatusId) { + lotStatusElement.value = lot.lotStatusId.toString(); + } + // eslint-disable-next-line no-unsanitized/method + modalElement + .querySelector('form') + ?.insertAdjacentHTML('beforeend', ``); + }, + onshown(modalElement, closeModalFunction) { + editCloseModalFunction = closeModalFunction; + bulmaJS.toggleHtmlClipped(); + modalElement + .querySelector('form') + ?.addEventListener('submit', doUpdateLotStatus); + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + } + }); + } + function deleteLot(clickEvent) { + const lotId = clickEvent.currentTarget.closest('.container--lot').dataset.lotId; + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrderLot`, { + workOrderId, + lotId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderLots = responseJSON.workOrderLots; + renderRelatedLotsAndOccupancies(); + } + else { + bulmaJS.alert({ + title: 'Error Deleting Relationship', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + bulmaJS.confirm({ + title: `Delete ${los.escapedAliases.Occupancy} Relationship`, + message: `Are you sure you want to remove the relationship to this ${los.escapedAliases.occupancy} record from this work order? Note that the record will remain.`, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Relationship', + callbackFunction: doDelete + } + }); + } + function renderRelatedLots() { + const lotsContainerElement = document.querySelector('#container--lots'); + document.querySelector(".tabs a[href='#relatedTab--lots'] .tag").textContent = workOrderLots.length.toString(); + if (workOrderLots.length === 0) { + // eslint-disable-next-line no-unsanitized/property + lotsContainerElement.innerHTML = `
    +

    There are no ${los.escapedAliases.lots} associated with this work order.

    +
    `; + return; + } + // eslint-disable-next-line no-unsanitized/property + lotsContainerElement.innerHTML = ` + + + + + + + + +
    ${los.escapedAliases.Lot}${los.escapedAliases.Map}${los.escapedAliases.Lot} TypeStatus
    `; + for (const lot of workOrderLots) { + const rowElement = document.createElement('tr'); + rowElement.className = 'container--lot'; + rowElement.dataset.lotId = lot.lotId.toString(); + // eslint-disable-next-line no-unsanitized/property + rowElement.innerHTML = ` + + ${cityssm.escapeHTML(lot.lotName ?? '')} + + + ${cityssm.escapeHTML(lot.mapName ?? '')} + + ${cityssm.escapeHTML(lot.lotType ?? '')} + + ${lot.lotStatusId + ? cityssm.escapeHTML(lot.lotStatus ?? '') + : '(No Status)'} + + + + `; + rowElement + .querySelector('.button--editLotStatus') + ?.addEventListener('click', openEditLotStatus); + rowElement + .querySelector('.button--deleteLot') + ?.addEventListener('click', deleteLot); + lotsContainerElement.querySelector('tbody')?.append(rowElement); + } + } + function renderRelatedLotsAndOccupancies() { + renderRelatedOccupancies(); + renderRelatedLots(); + } + renderRelatedLotsAndOccupancies(); + function doAddLotOccupancy(clickEvent) { + const rowElement = clickEvent.currentTarget.closest('tr'); + const lotOccupancyId = rowElement.dataset.lotOccupancyId ?? ''; + addLotOccupancy(lotOccupancyId, (success) => { + if (success) { + rowElement.remove(); + } + }); + } + document + .querySelector('#button--addLotOccupancy') + ?.addEventListener('click', () => { + let searchFormElement; + let searchResultsContainerElement; + function doSearch(event) { + if (event) { + event.preventDefault(); + } + // eslint-disable-next-line no-unsanitized/property + searchResultsContainerElement.innerHTML = + los.getLoadingParagraphHTML('Searching...'); + cityssm.postJSON(`${los.urlPrefix}/lotOccupancies/doSearchLotOccupancies`, searchFormElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.lotOccupancies.length === 0) { + searchResultsContainerElement.innerHTML = `
    +

    There are no records that meet the search criteria.

    +
    `; + return; + } + // eslint-disable-next-line no-unsanitized/property + searchResultsContainerElement.innerHTML = ` + + + + + + + + + +
    ${los.escapedAliases.Occupancy} Type${los.escapedAliases.Lot}${los.escapedAliases.OccupancyStartDate}End Date${los.escapedAliases.Occupants}
    `; + for (const lotOccupancy of responseJSON.lotOccupancies) { + const rowElement = document.createElement('tr'); + rowElement.className = 'container--lotOccupancy'; + rowElement.dataset.lotOccupancyId = + lotOccupancy.lotOccupancyId.toString(); + rowElement.innerHTML = ` + + + + ${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')} + `; + if (lotOccupancy.lotId) { + rowElement.insertAdjacentHTML('beforeend', `${cityssm.escapeHTML(lotOccupancy.lotName ?? '')}`); + } + else { + // eslint-disable-next-line no-unsanitized/method + rowElement.insertAdjacentHTML('beforeend', `(No ${los.escapedAliases.Lot})`); + } + // eslint-disable-next-line no-unsanitized/method + rowElement.insertAdjacentHTML('beforeend', ` + ${lotOccupancy.occupancyStartDateString} + + ${lotOccupancy.occupancyEndDate + ? lotOccupancy.occupancyEndDateString + : '(No End Date)'} + + ${lotOccupancy.lotOccupancyOccupants.length === 0 + ? ` + (No ${cityssm.escapeHTML(los.escapedAliases.Occupants)}) + ` + : cityssm.escapeHTML(`${lotOccupancy.lotOccupancyOccupants[0].occupantName} + ${lotOccupancy.lotOccupancyOccupants[0] + .occupantFamilyName}`) + + (lotOccupancy.lotOccupancyOccupants.length > 1 + ? ` plus + ${(lotOccupancy.lotOccupancyOccupants.length - 1).toString()}` + : '')}`); + rowElement + .querySelector('.button--addLotOccupancy') + ?.addEventListener('click', doAddLotOccupancy); + searchResultsContainerElement + .querySelector('tbody') + ?.append(rowElement); + } + }); + } + cityssm.openHtmlModal('workOrder-addLotOccupancy', { + onshow(modalElement) { + los.populateAliases(modalElement); + searchFormElement = modalElement.querySelector('form'); + searchResultsContainerElement = modalElement.querySelector('#resultsContainer--lotOccupancyAdd'); + modalElement.querySelector('#lotOccupancySearch--notWorkOrderId').value = workOrderId; + modalElement.querySelector('#lotOccupancySearch--occupancyEffectiveDateString').value = document.querySelector('#workOrderEdit--workOrderOpenDateString').value; + doSearch(); + }, + onshown(modalElement) { + bulmaJS.toggleHtmlClipped(); + const occupantNameElement = modalElement.querySelector('#lotOccupancySearch--occupantName'); + occupantNameElement.addEventListener('change', doSearch); + occupantNameElement.focus(); + modalElement.querySelector('#lotOccupancySearch--lotName').addEventListener('change', doSearch); + searchFormElement.addEventListener('submit', doSearch); + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + document.querySelector('#button--addLotOccupancy').focus(); + } + }); + }); + function doAddLot(clickEvent) { + const rowElement = clickEvent.currentTarget.closest('tr'); + const lotId = rowElement.dataset.lotId ?? ''; + addLot(lotId, (success) => { + if (success) { + rowElement.remove(); + } + }); + } + document + .querySelector('#button--addLot') + ?.addEventListener('click', () => { + let searchFormElement; + let searchResultsContainerElement; + function doSearch(event) { + if (event) { + event.preventDefault(); + } + // eslint-disable-next-line no-unsanitized/property + searchResultsContainerElement.innerHTML = + los.getLoadingParagraphHTML('Searching...'); + cityssm.postJSON(`${los.urlPrefix}/lots/doSearchLots`, searchFormElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.lots.length === 0) { + searchResultsContainerElement.innerHTML = `
    +

    There are no records that meet the search criteria.

    +
    `; + return; + } + // eslint-disable-next-line no-unsanitized/property + searchResultsContainerElement.innerHTML = ` + + + + + + + + +
    ${los.escapedAliases.Lot}${los.escapedAliases.Map}${los.escapedAliases.Lot} TypeStatus
    `; + for (const lot of responseJSON.lots) { + const rowElement = document.createElement('tr'); + rowElement.className = 'container--lot'; + rowElement.dataset.lotId = lot.lotId.toString(); + rowElement.innerHTML = ` + + + ${cityssm.escapeHTML(lot.lotName ?? '')} + + ${cityssm.escapeHTML(lot.mapName ?? '')} + + ${cityssm.escapeHTML(lot.lotType ?? '')} + + ${cityssm.escapeHTML(lot.lotStatus ?? '')} + `; + rowElement + .querySelector('.button--addLot') + ?.addEventListener('click', doAddLot); + searchResultsContainerElement + .querySelector('tbody') + ?.append(rowElement); + } + }); + } + cityssm.openHtmlModal('workOrder-addLot', { + onshow(modalElement) { + los.populateAliases(modalElement); + searchFormElement = modalElement.querySelector('form'); + searchResultsContainerElement = modalElement.querySelector('#resultsContainer--lotAdd'); + modalElement.querySelector('#lotSearch--notWorkOrderId').value = workOrderId; + const lotStatusElement = modalElement.querySelector('#lotSearch--lotStatusId'); + for (const lotStatus of exports.lotStatuses) { + const optionElement = document.createElement('option'); + optionElement.value = lotStatus.lotStatusId.toString(); + optionElement.textContent = lotStatus.lotStatus; + lotStatusElement.append(optionElement); + } + doSearch(); + }, + onshown(modalElement) { + bulmaJS.toggleHtmlClipped(); + const lotNameElement = modalElement.querySelector('#lotSearch--lotName'); + lotNameElement.addEventListener('change', doSearch); + lotNameElement.focus(); + modalElement + .querySelector('#lotSearch--lotStatusId') + ?.addEventListener('change', doSearch); + searchFormElement.addEventListener('submit', doSearch); + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + document.querySelector('#button--addLot').focus(); + } + }); + }); + })(); + } + /** + * Comments + */ + ; + (() => { + let workOrderComments = exports.workOrderComments; + delete exports.workOrderComments; + function openEditWorkOrderComment(clickEvent) { + const workOrderCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset + .workOrderCommentId ?? '', 10); + const workOrderComment = workOrderComments.find((currentComment) => { + return currentComment.workOrderCommentId === workOrderCommentId; + }); + let editFormElement; + let editCloseModalFunction; + function editComment(submitEvent) { + submitEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/workOrders/doUpdateWorkOrderComment`, editFormElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderComments = responseJSON.workOrderComments; + editCloseModalFunction(); + renderWorkOrderComments(); + } + else { + bulmaJS.alert({ + title: 'Error Updating Comment', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + cityssm.openHtmlModal('workOrder-editComment', { + onshow(modalElement) { + ; + modalElement.querySelector('#workOrderCommentEdit--workOrderId').value = workOrderId; + modalElement.querySelector('#workOrderCommentEdit--workOrderCommentId').value = workOrderCommentId.toString(); + modalElement.querySelector('#workOrderCommentEdit--workOrderComment').value = workOrderComment.workOrderComment ?? ''; + const workOrderCommentDateStringElement = modalElement.querySelector('#workOrderCommentEdit--workOrderCommentDateString'); + workOrderCommentDateStringElement.value = + workOrderComment.workOrderCommentDateString ?? ''; + const currentDateString = cityssm.dateToString(new Date()); + workOrderCommentDateStringElement.max = + workOrderComment.workOrderCommentDateString <= currentDateString + ? currentDateString + : workOrderComment.workOrderCommentDateString ?? ''; + modalElement.querySelector('#workOrderCommentEdit--workOrderCommentTimeString').value = workOrderComment.workOrderCommentTimeString ?? ''; + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped(); + los.initializeDatePickers(modalElement); + modalElement.querySelector('#workOrderCommentEdit--workOrderComment').focus(); + editFormElement = modalElement.querySelector('form'); + editFormElement.addEventListener('submit', editComment); + editCloseModalFunction = closeModalFunction; + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + } + }); + } + function deleteWorkOrderComment(clickEvent) { + const workOrderCommentId = Number.parseInt(clickEvent.currentTarget.closest('tr')?.dataset + .workOrderCommentId ?? '', 10); + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrderComment`, { + workOrderId, + workOrderCommentId + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderComments = responseJSON.workOrderComments; + renderWorkOrderComments(); + } + else { + bulmaJS.alert({ + title: 'Error Removing Comment', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + }); + } + bulmaJS.confirm({ + title: 'Remove Comment?', + message: 'Are you sure you want to remove this comment?', + okButton: { + text: 'Yes, Remove Comment', + callbackFunction: doDelete + }, + contextualColorName: 'warning' + }); + } + function renderWorkOrderComments() { + const containerElement = document.querySelector('#container--workOrderComments'); + if (workOrderComments.length === 0) { + containerElement.innerHTML = `
    +

    There are no comments to display.

    +
    `; + return; + } + const tableElement = document.createElement('table'); + tableElement.className = 'table is-fullwidth is-striped is-hoverable'; + tableElement.innerHTML = ` + Commentor + Comment Date + Comment + Options`; + for (const workOrderComment of workOrderComments) { + const tableRowElement = document.createElement('tr'); + tableRowElement.dataset.workOrderCommentId = + workOrderComment.workOrderCommentId?.toString(); + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` + ${cityssm.escapeHTML(workOrderComment.recordCreate_userName ?? '')} + + ${workOrderComment.workOrderCommentDateString} + ${workOrderComment.workOrderCommentTime === 0 + ? '' + : workOrderComment.workOrderCommentTimePeriodString} + + ${cityssm.escapeHTML(workOrderComment.workOrderComment ?? '')} + +
    + + +
    + `; + tableRowElement + .querySelector('.button--edit') + ?.addEventListener('click', openEditWorkOrderComment); + tableRowElement + .querySelector('.button--delete') + ?.addEventListener('click', deleteWorkOrderComment); + tableElement.querySelector('tbody')?.append(tableRowElement); + } + containerElement.innerHTML = ''; + containerElement.append(tableElement); + } + function openAddCommentModal() { + let addCommentCloseModalFunction; + function doAddComment(formEvent) { + formEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderComment`, formEvent.currentTarget, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderComments = responseJSON.workOrderComments; + renderWorkOrderComments(); + addCommentCloseModalFunction(); + } + }); + } + cityssm.openHtmlModal('workOrder-addComment', { + onshow(modalElement) { + los.populateAliases(modalElement); + modalElement.querySelector('#workOrderCommentAdd--workOrderId').value = workOrderId; + modalElement + .querySelector('form') + ?.addEventListener('submit', doAddComment); + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped(); + addCommentCloseModalFunction = closeModalFunction; + modalElement.querySelector('#workOrderCommentAdd--workOrderComment').focus(); + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + document.querySelector('#workOrderComments--add').focus(); + } + }); + } + document + .querySelector('#workOrderComments--add') + ?.addEventListener('click', openAddCommentModal); + if (!isCreate) { + renderWorkOrderComments(); + } + })(); + /* + * Milestones + */ + function clearPanelBlockElements(panelElement) { + for (const panelBlockElement of panelElement.querySelectorAll('.panel-block')) { + panelBlockElement.remove(); + } + } + function refreshConflictingMilestones(workOrderMilestoneDateString, targetPanelElement) { + // Clear panel-block elements + clearPanelBlockElements(targetPanelElement); + // eslint-disable-next-line no-unsanitized/method + targetPanelElement.insertAdjacentHTML('beforeend', `
    + ${los.getLoadingParagraphHTML('Loading conflicting milestones...')} +
    `); + cityssm.postJSON(`${los.urlPrefix}/workOrders/doGetWorkOrderMilestones`, { + workOrderMilestoneDateFilter: 'date', + workOrderMilestoneDateString + }, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + const workOrderMilestones = responseJSON.workOrderMilestones.filter((possibleMilestone) => { + return possibleMilestone.workOrderId.toString() !== workOrderId; + }); + clearPanelBlockElements(targetPanelElement); + for (const milestone of workOrderMilestones) { + targetPanelElement.insertAdjacentHTML('beforeend', `
    +
    +
    + ${cityssm.escapeHTML(milestone.workOrderMilestoneTime === 0 ? 'No Time' : milestone.workOrderMilestoneTimePeriodString ?? '')}
    + ${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')} +
    +
    + ${cityssm.escapeHTML(milestone.workOrderNumber ?? '')}
    + + ${cityssm.escapeHTML(milestone.workOrderDescription ?? '')} + +
    +
    +
    `); + } + if (workOrderMilestones.length === 0) { + targetPanelElement.insertAdjacentHTML('beforeend', `
    +
    +

    + There are no milestones on other work orders scheduled for + ${cityssm.escapeHTML(workOrderMilestoneDateString)}. +

    +
    +
    `); + } + }); + } + function processMilestoneResponse(rawResponseJSON) { + const responseJSON = rawResponseJSON; + if (responseJSON.success) { + workOrderMilestones = responseJSON.workOrderMilestones; + renderMilestones(); + } + else { + bulmaJS.alert({ + title: 'Error Reopening Milestone', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }); + } + } + function completeMilestone(clickEvent) { + clickEvent.preventDefault(); + const currentDateString = cityssm.dateToString(new Date()); + const workOrderMilestoneId = Number.parseInt(clickEvent.currentTarget.closest('.container--milestone').dataset.workOrderMilestoneId ?? '', 10); + const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { + return currentMilestone.workOrderMilestoneId === workOrderMilestoneId; + }); + function doComplete() { + cityssm.postJSON(`${los.urlPrefix}/workOrders/doCompleteWorkOrderMilestone`, { + workOrderId, + workOrderMilestoneId + }, processMilestoneResponse); + } + bulmaJS.confirm({ + title: 'Complete Milestone', + message: `Are you sure you want to complete this milestone? + ${workOrderMilestone.workOrderMilestoneDateString !== undefined && + workOrderMilestone.workOrderMilestoneDateString !== '' && + workOrderMilestone.workOrderMilestoneDateString > currentDateString + ? '
    Note that this milestone is expected to be completed in the future.' + : ''}`, + messageIsHtml: true, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Complete Milestone', + callbackFunction: doComplete + } + }); + } + function reopenMilestone(clickEvent) { + clickEvent.preventDefault(); + const workOrderMilestoneId = clickEvent.currentTarget.closest('.container--milestone').dataset.workOrderMilestoneId; + function doReopen() { + cityssm.postJSON(`${los.urlPrefix}/workOrders/doReopenWorkOrderMilestone`, { + workOrderId, + workOrderMilestoneId + }, processMilestoneResponse); + } + bulmaJS.confirm({ + title: 'Reopen Milestone', + message: 'Are you sure you want to remove the completion status from this milestone, and reopen it?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Reopen Milestone', + callbackFunction: doReopen + } + }); + } + function deleteMilestone(clickEvent) { + clickEvent.preventDefault(); + const workOrderMilestoneId = clickEvent.currentTarget.closest('.container--milestone').dataset.workOrderMilestoneId; + function doDelete() { + cityssm.postJSON(`${los.urlPrefix}/workOrders/doDeleteWorkOrderMilestone`, { + workOrderMilestoneId, + workOrderId + }, processMilestoneResponse); + } + bulmaJS.confirm({ + title: 'Delete Milestone', + message: 'Are you sure you want to delete this milestone?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Milestone', + callbackFunction: doDelete + } + }); + } + function editMilestone(clickEvent) { + clickEvent.preventDefault(); + const workOrderMilestoneId = Number.parseInt(clickEvent.currentTarget.closest('.container--milestone').dataset.workOrderMilestoneId ?? '', 10); + const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { + return currentMilestone.workOrderMilestoneId === workOrderMilestoneId; + }); + let editCloseModalFunction; + let workOrderMilestoneDateStringElement; + function doEdit(submitEvent) { + submitEvent.preventDefault(); + cityssm.postJSON(`${los.urlPrefix}/workOrders/doUpdateWorkOrderMilestone`, submitEvent.currentTarget, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + processMilestoneResponse(responseJSON); + if (responseJSON.success) { + editCloseModalFunction(); + } + }); + } + cityssm.openHtmlModal('workOrder-editMilestone', { + onshow(modalElement) { + ; + modalElement.querySelector('#milestoneEdit--workOrderId').value = workOrderId; + modalElement.querySelector('#milestoneEdit--workOrderMilestoneId').value = workOrderMilestone.workOrderMilestoneId?.toString() ?? ''; + const milestoneTypeElement = modalElement.querySelector('#milestoneEdit--workOrderMilestoneTypeId'); + let milestoneTypeFound = false; + for (const milestoneType of exports.workOrderMilestoneTypes) { + const optionElement = document.createElement('option'); + optionElement.value = + milestoneType.workOrderMilestoneTypeId.toString(); + optionElement.textContent = milestoneType.workOrderMilestoneType; + if (milestoneType.workOrderMilestoneTypeId === + workOrderMilestone.workOrderMilestoneTypeId) { + optionElement.selected = true; + milestoneTypeFound = true; + } + milestoneTypeElement.append(optionElement); + } + if (!milestoneTypeFound && + workOrderMilestone.workOrderMilestoneTypeId) { + const optionElement = document.createElement('option'); + optionElement.value = + workOrderMilestone.workOrderMilestoneTypeId.toString(); + optionElement.textContent = + workOrderMilestone.workOrderMilestoneType ?? ''; + optionElement.selected = true; + milestoneTypeElement.append(optionElement); + } + workOrderMilestoneDateStringElement = modalElement.querySelector('#milestoneEdit--workOrderMilestoneDateString'); + workOrderMilestoneDateStringElement.value = + workOrderMilestone.workOrderMilestoneDateString ?? ''; + if (workOrderMilestone.workOrderMilestoneTime) { + ; + modalElement.querySelector('#milestoneEdit--workOrderMilestoneTimeString').value = workOrderMilestone.workOrderMilestoneTimeString ?? ''; + } + ; + modalElement.querySelector('#milestoneEdit--workOrderMilestoneDescription').value = workOrderMilestone.workOrderMilestoneDescription ?? ''; + }, + onshown(modalElement, closeModalFunction) { + editCloseModalFunction = closeModalFunction; + bulmaJS.toggleHtmlClipped(); + los.initializeDatePickers(modalElement); + // los.initializeTimePickers(modalElement); + modalElement.querySelector('form')?.addEventListener('submit', doEdit); + const conflictingMilestonePanelElement = document.querySelector('#milestoneEdit--conflictingMilestonesPanel'); + workOrderMilestoneDateStringElement.addEventListener('change', () => { + refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement); + }); + refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement); + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + } + }); + } + function renderMilestones() { + // Clear milestones panel + const milestonesPanelElement = document.querySelector('#panel--milestones'); + const panelBlockElementsToDelete = milestonesPanelElement.querySelectorAll('.panel-block'); + for (const panelBlockToDelete of panelBlockElementsToDelete) { + panelBlockToDelete.remove(); + } + for (const milestone of workOrderMilestones) { + const panelBlockElement = document.createElement('div'); + panelBlockElement.className = 'panel-block is-block container--milestone'; + panelBlockElement.dataset.workOrderMilestoneId = + milestone.workOrderMilestoneId?.toString(); + // eslint-disable-next-line no-unsanitized/property + panelBlockElement.innerHTML = `
    +
    + ${milestone.workOrderMilestoneCompletionDate + ? ` + + ` + : ``} +
    + ${milestone.workOrderMilestoneTypeId + ? `${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')}
    ` + : ''} + ${milestone.workOrderMilestoneDate === 0 + ? '(No Set Date)' + : milestone.workOrderMilestoneDateString} + ${milestone.workOrderMilestoneTime + ? ` ${milestone.workOrderMilestoneTimePeriodString}` + : ''}
    + + ${cityssm.escapeHTML(milestone.workOrderMilestoneDescription ?? '')} + +
    + +
    `; + panelBlockElement + .querySelector('.button--reopenMilestone') + ?.addEventListener('click', reopenMilestone); + panelBlockElement + .querySelector('.button--editMilestone') + ?.addEventListener('click', editMilestone); + panelBlockElement + .querySelector('.button--completeMilestone') + ?.addEventListener('click', completeMilestone); + panelBlockElement + .querySelector('.button--deleteMilestone') + ?.addEventListener('click', deleteMilestone); + milestonesPanelElement.append(panelBlockElement); + } + bulmaJS.init(milestonesPanelElement); + } + if (!isCreate) { + workOrderMilestones = exports.workOrderMilestones; + delete exports.workOrderMilestones; + renderMilestones(); + document + .querySelector('#button--addMilestone') + ?.addEventListener('click', () => { + let addFormElement; + let workOrderMilestoneDateStringElement; + let addCloseModalFunction; + function doAdd(submitEvent) { + if (submitEvent) { + submitEvent.preventDefault(); + } + const currentDateString = cityssm.dateToString(new Date()); + function _doAdd() { + cityssm.postJSON(`${los.urlPrefix}/workOrders/doAddWorkOrderMilestone`, addFormElement, (rawResponseJSON) => { + const responseJSON = rawResponseJSON; + processMilestoneResponse(responseJSON); + if (responseJSON.success) { + addCloseModalFunction(); + } + }); + } + const milestoneDateString = workOrderMilestoneDateStringElement.value; + if (milestoneDateString !== '' && + milestoneDateString < currentDateString) { + bulmaJS.confirm({ + title: 'Milestone Date in the Past', + message: 'Are you sure you want to create a milestone with a date in the past?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Create a Past Milestone', + callbackFunction: _doAdd + } + }); + } + else { + _doAdd(); + } + } + cityssm.openHtmlModal('workOrder-addMilestone', { + onshow(modalElement) { + ; + modalElement.querySelector('#milestoneAdd--workOrderId').value = workOrderId; + const milestoneTypeElement = modalElement.querySelector('#milestoneAdd--workOrderMilestoneTypeId'); + for (const milestoneType of exports.workOrderMilestoneTypes) { + const optionElement = document.createElement('option'); + optionElement.value = + milestoneType.workOrderMilestoneTypeId.toString(); + optionElement.textContent = milestoneType.workOrderMilestoneType; + milestoneTypeElement.append(optionElement); + } + workOrderMilestoneDateStringElement = modalElement.querySelector('#milestoneAdd--workOrderMilestoneDateString'); + workOrderMilestoneDateStringElement.valueAsDate = new Date(); + }, + onshown(modalElement, closeModalFunction) { + addCloseModalFunction = closeModalFunction; + los.initializeDatePickers(modalElement); + // los.initializeTimePickers(modalElement); + bulmaJS.toggleHtmlClipped(); + modalElement.querySelector('#milestoneAdd--workOrderMilestoneTypeId').focus(); + addFormElement = modalElement.querySelector('form'); + addFormElement.addEventListener('submit', doAdd); + const conflictingMilestonePanelElement = document.querySelector('#milestoneAdd--conflictingMilestonesPanel'); + workOrderMilestoneDateStringElement.addEventListener('change', () => { + refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement); + }); + refreshConflictingMilestones(workOrderMilestoneDateStringElement.value, conflictingMilestonePanelElement); + }, + onremoved() { + bulmaJS.toggleHtmlClipped(); + document.querySelector('#button--addMilestone').focus(); + } + }); + }); + } +})(); diff --git a/public/javascripts/workOrderEdit.min.js b/public/javascripts/workOrderEdit.min.js deleted file mode 100644 index e8f865ed..00000000 --- a/public/javascripts/workOrderEdit.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e,t;const o=exports.los,n=document.querySelector("#workOrderEdit--workOrderId").value,r=""===n,s=document.querySelector("#form--workOrderEdit");function a(){var e;o.setUnsavedChanges(),null===(e=document.querySelector("button[type='submit'][form='form--workOrderEdit']"))||void 0===e||e.classList.remove("is-light")}function l(){var e;o.clearUnsavedChanges(),null===(e=document.querySelector("button[type='submit'][form='form--workOrderEdit']"))||void 0===e||e.classList.add("is-light")}o.initializeDatePickers(null===(S=s.querySelector("#workOrderEdit--workOrderOpenDateString"))||void 0===S?void 0:S.closest(".field")),o.initializeUnlockFieldButtons(s),s.addEventListener("submit",e=>{e.preventDefault(),cityssm.postJSON(`${o.urlPrefix}/workOrders/${r?"doCreateWorkOrder":"doUpdateWorkOrder"}`,e.currentTarget,e=>{var t;const n=e;n.success?(l(),r?window.location.href=o.getWorkOrderURL(n.workOrderId,!0):bulmaJS.alert({message:"Work Order Updated Successfully",contextualColorName:"success"})):bulmaJS.alert({title:"Error Updating Work Order",message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})});const i=s.querySelectorAll("input, select, textarea");for(const e of i)e.addEventListener("change",a);function d(){cityssm.postJSON(`${o.urlPrefix}/workOrders/doCloseWorkOrder`,{workOrderId:n},e=>{var t;const r=e;r.success?(l(),window.location.href=o.getWorkOrderURL(n)):bulmaJS.alert({title:"Error Closing Work Order",message:null!==(t=r.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}function c(){cityssm.postJSON(`${o.urlPrefix}/workOrders/doDeleteWorkOrder`,{workOrderId:n},e=>{var t;const n=e;n.success?(l(),window.location.href=`${o.urlPrefix}/workOrders`):bulmaJS.alert({title:"Error Deleting Work Order",message:null!==(t=n.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}let u;if(null===(m=document.querySelector("#button--closeWorkOrder"))||void 0===m||m.addEventListener("click",()=>{u.some(e=>!e.workOrderMilestoneCompletionDate)?bulmaJS.alert({title:"Outstanding Milestones",message:"You cannot close a work order with outstanding milestones.\n Either complete the outstanding milestones, or remove them from the work order.",contextualColorName:"warning"}):bulmaJS.confirm({title:"Close Work Order",message:o.hasUnsavedChanges()?"Are you sure you want to close this work order with unsaved changes?":"Are you sure you want to close this work order?",contextualColorName:o.hasUnsavedChanges()?"warning":"info",okButton:{text:"Yes, Close Work Order",callbackFunction:d}})}),null===(e=document.querySelector("#button--deleteWorkOrder"))||void 0===e||e.addEventListener("click",e=>{e.preventDefault(),bulmaJS.confirm({title:"Delete Work Order",message:"Are you sure you want to delete this work order?",contextualColorName:"warning",okButton:{text:"Yes, Delete Work Order",callbackFunction:c}})}),!r){var m;Object.defineProperty(exports,"__esModule",{value:!0});let e=exports.workOrderLots;delete exports.workOrderLots;let t=exports.workOrderLotOccupancies;function p(e){const r=e.currentTarget.closest(".container--lotOccupancy").dataset.lotOccupancyId;bulmaJS.confirm({title:`Delete ${o.escapedAliases.Occupancy} Relationship`,message:`Are you sure you want to remove the relationship to this ${o.escapedAliases.occupancy} record from this work order? Note that the record will remain.`,contextualColorName:"warning",okButton:{text:"Yes, Delete Relationship",callbackFunction:function(){cityssm.postJSON(`${o.urlPrefix}/workOrders/doDeleteWorkOrderLotOccupancy`,{workOrderId:n,lotOccupancyId:r},e=>{var o;const n=e;n.success?(t=n.workOrderLotOccupancies,g()):bulmaJS.alert({title:"Error Deleting Relationship",message:null!==(o=n.errorMessage)&&void 0!==o?o:"",contextualColorName:"danger"})})}}})}function v(t,r){cityssm.postJSON(`${o.urlPrefix}/workOrders/doAddWorkOrderLot`,{workOrderId:n,lotId:t},t=>{var n;const s=t;s.success?(e=s.workOrderLots,g()):bulmaJS.alert({title:`Error Adding ${o.escapedAliases.Lot}`,message:null!==(n=s.errorMessage)&&void 0!==n?n:"",contextualColorName:"danger"}),void 0!==r&&r(s.success)})}function y(e){var t;v(null!==(t=e.currentTarget.dataset.lotId)&&void 0!==t?t:"")}function O(t){var r;const s=Number.parseInt(null!==(r=t.currentTarget.closest(".container--lot").dataset.lotId)&&void 0!==r?r:"",10),a=e.find(e=>e.lotId===s);let l;function i(t){t.preventDefault(),cityssm.postJSON(`${o.urlPrefix}/workOrders/doUpdateLotStatus`,t.currentTarget,t=>{var o;const n=t;n.success?(e=n.workOrderLots,g(),l()):bulmaJS.alert({title:"Error Deleting Relationship",message:null!==(o=n.errorMessage)&&void 0!==o?o:"",contextualColorName:"danger"})})}cityssm.openHtmlModal("lot-editLotStatus",{onshow(e){var t,r,l;o.populateAliases(e),e.querySelector("#lotStatusEdit--lotId").value=s.toString(),e.querySelector("#lotStatusEdit--lotName").value=null!==(t=a.lotName)&&void 0!==t?t:"";const i=e.querySelector("#lotStatusEdit--lotStatusId");let d=!1;for(const e of exports.lotStatuses){const t=document.createElement("option");t.value=e.lotStatusId.toString(),t.textContent=e.lotStatus,e.lotStatusId===a.lotStatusId&&(d=!0),i.append(t)}if(!d&&a.lotStatusId){const e=document.createElement("option");e.value=a.lotStatusId.toString(),e.textContent=null!==(r=a.lotStatus)&&void 0!==r?r:"",i.append(e)}a.lotStatusId&&(i.value=a.lotStatusId.toString()),null===(l=e.querySelector("form"))||void 0===l||l.insertAdjacentHTML("beforeend",``)},onshown(e,t){var o;l=t,bulmaJS.toggleHtmlClipped(),null===(o=e.querySelector("form"))||void 0===o||o.addEventListener("submit",i)},onremoved(){bulmaJS.toggleHtmlClipped()}})}function h(t){const r=t.currentTarget.closest(".container--lot").dataset.lotId;bulmaJS.confirm({title:`Delete ${o.escapedAliases.Occupancy} Relationship`,message:`Are you sure you want to remove the relationship to this ${o.escapedAliases.occupancy} record from this work order? Note that the record will remain.`,contextualColorName:"warning",okButton:{text:"Yes, Delete Relationship",callbackFunction:function(){cityssm.postJSON(`${o.urlPrefix}/workOrders/doDeleteWorkOrderLot`,{workOrderId:n,lotId:r},t=>{var o;const n=t;n.success?(e=n.workOrderLots,g()):bulmaJS.alert({title:"Error Deleting Relationship",message:null!==(o=n.errorMessage)&&void 0!==o?o:"",contextualColorName:"danger"})})}}})}function g(){!function(){var n,r,s,a,l,i,d,c,u,m;const v=document.querySelector("#container--lotOccupancies");if(document.querySelector(".tabs a[href='#relatedTab--lotOccupancies'] .tag").textContent=t.length.toString(),0===t.length)return void(v.innerHTML=`
    \n

    There are no ${o.escapedAliases.occupancies} associated with this work order.

    \n
    `);v.innerHTML=`\n \n \n \n \n \n \n \n \n \n \n
    ${o.escapedAliases.Occupancy} Type${o.escapedAliases.Lot}${o.escapedAliases.OccupancyStartDate}End Date${o.escapedAliases.Occupants}
    `;const O=cityssm.dateToString(new Date);for(const h of t){const t=document.createElement("tr");t.className="container--lotOccupancy",t.dataset.lotOccupancyId=h.lotOccupancyId.toString();const g=!(h.occupancyEndDate&&h.occupancyEndDateStringh.lotId===e.lotId);t.innerHTML=`\n ${g?``:``}\n \n \n ${cityssm.escapeHTML(null!==(n=h.occupancyType)&&void 0!==n?n:"")}\n
    \n #${h.lotOccupancyId}\n `,h.lotId?t.insertAdjacentHTML("beforeend",`\n ${cityssm.escapeHTML(null!==(r=h.lotName)&&void 0!==r?r:"")}\n ${k?"":` `}\n `):t.insertAdjacentHTML("beforeend",`(No ${o.escapedAliases.Lot})`);let w="";for(const e of h.lotOccupancyOccupants)w+=`
  • \n \n \n \n ${cityssm.escapeHTML(null!==(i=e.occupantName)&&void 0!==i?i:"")}\n ${cityssm.escapeHTML(null!==(d=e.occupantFamilyName)&&void 0!==d?d:"")}\n
  • `;t.insertAdjacentHTML("beforeend",`\n ${h.occupancyStartDateString}\n \n ${h.occupancyEndDate?h.occupancyEndDateString:'(No End Date)'}\n \n ${0===h.lotOccupancyOccupants.length?`(No ${o.escapedAliases.Occupants})`:`
      ${w}
    `}\n \n \n `),null===(c=t.querySelector(".button--addLot"))||void 0===c||c.addEventListener("click",y),null===(u=t.querySelector(".button--deleteLotOccupancy"))||void 0===u||u.addEventListener("click",p),null===(m=v.querySelector("tbody"))||void 0===m||m.append(t)}}(),function(){var t,n,r,s,a,l,i;const d=document.querySelector("#container--lots");if(document.querySelector(".tabs a[href='#relatedTab--lots'] .tag").textContent=e.length.toString(),0!==e.length){d.innerHTML=`\n \n \n \n \n \n \n \n \n
    ${o.escapedAliases.Lot}${o.escapedAliases.Map}${o.escapedAliases.Lot} TypeStatus
    `;for(const c of e){const e=document.createElement("tr");e.className="container--lot",e.dataset.lotId=c.lotId.toString(),e.innerHTML=`\n \n ${cityssm.escapeHTML(null!==(t=c.lotName)&&void 0!==t?t:"")}\n \n \n ${cityssm.escapeHTML(null!==(n=c.mapName)&&void 0!==n?n:"")}\n \n ${cityssm.escapeHTML(null!==(r=c.lotType)&&void 0!==r?r:"")}\n \n ${c.lotStatusId?cityssm.escapeHTML(null!==(s=c.lotStatus)&&void 0!==s?s:""):'(No Status)'}\n \n \n \n `,null===(a=e.querySelector(".button--editLotStatus"))||void 0===a||a.addEventListener("click",O),null===(l=e.querySelector(".button--deleteLot"))||void 0===l||l.addEventListener("click",h),null===(i=d.querySelector("tbody"))||void 0===i||i.append(e)}}else d.innerHTML=`
    \n

    There are no ${o.escapedAliases.lots} associated with this work order.

    \n
    `}()}function k(e){var r;const s=e.currentTarget.closest("tr");!function(e,r){cityssm.postJSON(`${o.urlPrefix}/workOrders/doAddWorkOrderLotOccupancy`,{workOrderId:n,lotOccupancyId:e},e=>{var n;const s=e;s.success?(t=s.workOrderLotOccupancies,g()):bulmaJS.alert({title:`Error Adding ${o.escapedAliases.Occupancy}`,message:null!==(n=s.errorMessage)&&void 0!==n?n:"",contextualColorName:"danger"}),void 0!==r&&r(s.success)})}(null!==(r=s.dataset.lotOccupancyId)&&void 0!==r?r:"",e=>{e&&s.remove()})}function w(e){var t;const o=e.currentTarget.closest("tr");v(null!==(t=o.dataset.lotId)&&void 0!==t?t:"",e=>{e&&o.remove()})}delete exports.workOrderLotOccupancies,g(),null===(S=document.querySelector("#button--addLotOccupancy"))||void 0===S||S.addEventListener("click",()=>{let e,t;function r(n){n&&n.preventDefault(),t.innerHTML=o.getLoadingParagraphHTML("Searching..."),cityssm.postJSON(`${o.urlPrefix}/lotOccupancies/doSearchLotOccupancies`,e,e=>{var n,r,s,a;const l=e;if(0!==l.lotOccupancies.length){t.innerHTML=`\n \n \n \n \n \n \n \n \n \n
    ${o.escapedAliases.Occupancy} Type${o.escapedAliases.Lot}${o.escapedAliases.OccupancyStartDate}End Date${o.escapedAliases.Occupants}
    `;for(const e of l.lotOccupancies){const l=document.createElement("tr");l.className="container--lotOccupancy",l.dataset.lotOccupancyId=e.lotOccupancyId.toString(),l.innerHTML=`\n \n \n \n ${cityssm.escapeHTML(null!==(n=e.occupancyType)&&void 0!==n?n:"")}\n `,e.lotId?l.insertAdjacentHTML("beforeend",`${cityssm.escapeHTML(null!==(r=e.lotName)&&void 0!==r?r:"")}`):l.insertAdjacentHTML("beforeend",`(No ${o.escapedAliases.Lot})`),l.insertAdjacentHTML("beforeend",`\n ${e.occupancyStartDateString}\n \n ${e.occupancyEndDate?e.occupancyEndDateString:'(No End Date)'}\n \n ${0===e.lotOccupancyOccupants.length?`\n (No ${cityssm.escapeHTML(o.escapedAliases.Occupants)})\n `:cityssm.escapeHTML(`${e.lotOccupancyOccupants[0].occupantName}\n ${e.lotOccupancyOccupants[0].occupantFamilyName}`)+(e.lotOccupancyOccupants.length>1?` plus\n ${(e.lotOccupancyOccupants.length-1).toString()}`:"")}`),null===(s=l.querySelector(".button--addLotOccupancy"))||void 0===s||s.addEventListener("click",k),null===(a=t.querySelector("tbody"))||void 0===a||a.append(l)}}else t.innerHTML='
    \n

    There are no records that meet the search criteria.

    \n
    '})}cityssm.openHtmlModal("workOrder-addLotOccupancy",{onshow(s){o.populateAliases(s),e=s.querySelector("form"),t=s.querySelector("#resultsContainer--lotOccupancyAdd"),s.querySelector("#lotOccupancySearch--notWorkOrderId").value=n,s.querySelector("#lotOccupancySearch--occupancyEffectiveDateString").value=document.querySelector("#workOrderEdit--workOrderOpenDateString").value,r()},onshown(t){bulmaJS.toggleHtmlClipped();const o=t.querySelector("#lotOccupancySearch--occupantName");o.addEventListener("change",r),o.focus(),t.querySelector("#lotOccupancySearch--lotName").addEventListener("change",r),e.addEventListener("submit",r)},onremoved(){bulmaJS.toggleHtmlClipped(),document.querySelector("#button--addLotOccupancy").focus()}})}),null===(m=document.querySelector("#button--addLot"))||void 0===m||m.addEventListener("click",()=>{let e,t;function r(n){n&&n.preventDefault(),t.innerHTML=o.getLoadingParagraphHTML("Searching..."),cityssm.postJSON(`${o.urlPrefix}/lots/doSearchLots`,e,e=>{var n,r,s,a,l,i;const d=e;if(0!==d.lots.length){t.innerHTML=`\n \n \n \n \n \n \n \n \n
    ${o.escapedAliases.Lot}${o.escapedAliases.Map}${o.escapedAliases.Lot} TypeStatus
    `;for(const e of d.lots){const o=document.createElement("tr");o.className="container--lot",o.dataset.lotId=e.lotId.toString(),o.innerHTML=`\n \n \n ${cityssm.escapeHTML(null!==(n=e.lotName)&&void 0!==n?n:"")}\n \n ${cityssm.escapeHTML(null!==(r=e.mapName)&&void 0!==r?r:"")}\n \n ${cityssm.escapeHTML(null!==(s=e.lotType)&&void 0!==s?s:"")}\n \n ${cityssm.escapeHTML(null!==(a=e.lotStatus)&&void 0!==a?a:"")}\n `,null===(l=o.querySelector(".button--addLot"))||void 0===l||l.addEventListener("click",w),null===(i=t.querySelector("tbody"))||void 0===i||i.append(o)}}else t.innerHTML='
    \n

    There are no records that meet the search criteria.

    \n
    '})}cityssm.openHtmlModal("workOrder-addLot",{onshow(s){o.populateAliases(s),e=s.querySelector("form"),t=s.querySelector("#resultsContainer--lotAdd"),s.querySelector("#lotSearch--notWorkOrderId").value=n;const a=s.querySelector("#lotSearch--lotStatusId");for(const e of exports.lotStatuses){const t=document.createElement("option");t.value=e.lotStatusId.toString(),t.textContent=e.lotStatus,a.append(t)}r()},onshown(t){var o;bulmaJS.toggleHtmlClipped();const n=t.querySelector("#lotSearch--lotName");n.addEventListener("change",r),n.focus(),null===(o=t.querySelector("#lotSearch--lotStatusId"))||void 0===o||o.addEventListener("change",r),e.addEventListener("submit",r)},onremoved(){bulmaJS.toggleHtmlClipped(),document.querySelector("#button--addLot").focus()}})})}var S;Object.defineProperty(exports,"__esModule",{value:!0});let f=exports.workOrderComments;function b(e){var t,r;const s=Number.parseInt(null!==(r=null===(t=e.currentTarget.closest("tr"))||void 0===t?void 0:t.dataset.workOrderCommentId)&&void 0!==r?r:"",10),a=f.find(e=>e.workOrderCommentId===s);let l,i;function d(e){e.preventDefault(),cityssm.postJSON(`${o.urlPrefix}/workOrders/doUpdateWorkOrderComment`,l,e=>{var t;const o=e;o.success?(f=o.workOrderComments,i(),L()):bulmaJS.alert({title:"Error Updating Comment",message:null!==(t=o.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}cityssm.openHtmlModal("workOrder-editComment",{onshow(e){var t,o,r,l;e.querySelector("#workOrderCommentEdit--workOrderId").value=n,e.querySelector("#workOrderCommentEdit--workOrderCommentId").value=s.toString(),e.querySelector("#workOrderCommentEdit--workOrderComment").value=null!==(t=a.workOrderComment)&&void 0!==t?t:"";const i=e.querySelector("#workOrderCommentEdit--workOrderCommentDateString");i.value=null!==(o=a.workOrderCommentDateString)&&void 0!==o?o:"";const d=cityssm.dateToString(new Date);i.max=a.workOrderCommentDateString<=d?d:null!==(r=a.workOrderCommentDateString)&&void 0!==r?r:"",e.querySelector("#workOrderCommentEdit--workOrderCommentTimeString").value=null!==(l=a.workOrderCommentTimeString)&&void 0!==l?l:""},onshown(e,t){bulmaJS.toggleHtmlClipped(),o.initializeDatePickers(e),e.querySelector("#workOrderCommentEdit--workOrderComment").focus(),(l=e.querySelector("form")).addEventListener("submit",d),i=t},onremoved(){bulmaJS.toggleHtmlClipped()}})}function M(e){var t,r;const s=Number.parseInt(null!==(r=null===(t=e.currentTarget.closest("tr"))||void 0===t?void 0:t.dataset.workOrderCommentId)&&void 0!==r?r:"",10);bulmaJS.confirm({title:"Remove Comment?",message:"Are you sure you want to remove this comment?",okButton:{text:"Yes, Remove Comment",callbackFunction:function(){cityssm.postJSON(`${o.urlPrefix}/workOrders/doDeleteWorkOrderComment`,{workOrderId:n,workOrderCommentId:s},e=>{var t;const o=e;o.success?(f=o.workOrderComments,L()):bulmaJS.alert({title:"Error Removing Comment",message:null!==(t=o.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})})}},contextualColorName:"warning"})}function L(){var e,t,o,n,r,s;const a=document.querySelector("#container--workOrderComments");if(0===f.length)return void(a.innerHTML='
    \n

    There are no comments to display.

    \n
    ');const l=document.createElement("table");l.className="table is-fullwidth is-striped is-hoverable",l.innerHTML='\n Commentor\n Comment Date\n Comment\n Options';for(const a of f){const i=document.createElement("tr");i.dataset.workOrderCommentId=null===(e=a.workOrderCommentId)||void 0===e?void 0:e.toString(),i.innerHTML=`\n ${cityssm.escapeHTML(null!==(t=a.recordCreate_userName)&&void 0!==t?t:"")}\n \n ${a.workOrderCommentDateString}\n ${0===a.workOrderCommentTime?"":a.workOrderCommentTimePeriodString}\n \n ${cityssm.escapeHTML(null!==(o=a.workOrderComment)&&void 0!==o?o:"")}\n \n
    \n \n \n
    \n `,null===(n=i.querySelector(".button--edit"))||void 0===n||n.addEventListener("click",b),null===(r=i.querySelector(".button--delete"))||void 0===r||r.addEventListener("click",M),null===(s=l.querySelector("tbody"))||void 0===s||s.append(i)}a.innerHTML="",a.append(l)}function T(e){for(const t of e.querySelectorAll(".panel-block"))t.remove()}function C(e,t){T(t),t.insertAdjacentHTML("beforeend",`
    \n ${o.getLoadingParagraphHTML("Loading conflicting milestones...")}\n
    `),cityssm.postJSON(`${o.urlPrefix}/workOrders/doGetWorkOrderMilestones`,{workOrderMilestoneDateFilter:"date",workOrderMilestoneDateString:e},o=>{var r,s,a,l;const i=o.workOrderMilestones.filter(e=>e.workOrderId.toString()!==n);T(t);for(const e of i)t.insertAdjacentHTML("beforeend",`
    \n
    \n
    \n ${cityssm.escapeHTML(0===e.workOrderMilestoneTime?"No Time":null!==(r=e.workOrderMilestoneTimePeriodString)&&void 0!==r?r:"")}
    \n ${cityssm.escapeHTML(null!==(s=e.workOrderMilestoneType)&&void 0!==s?s:"")}\n
    \n
    \n ${cityssm.escapeHTML(null!==(a=e.workOrderNumber)&&void 0!==a?a:"")}
    \n \n ${cityssm.escapeHTML(null!==(l=e.workOrderDescription)&&void 0!==l?l:"")}\n \n
    \n
    \n
    `);0===i.length&&t.insertAdjacentHTML("beforeend",`
    \n
    \n

    \n There are no milestones on other work orders scheduled for\n ${cityssm.escapeHTML(e)}.\n

    \n
    \n
    `)})}function $(e){var t;const o=e;o.success?(u=o.workOrderMilestones,q()):bulmaJS.alert({title:"Error Reopening Milestone",message:null!==(t=o.errorMessage)&&void 0!==t?t:"",contextualColorName:"danger"})}function I(e){var t;e.preventDefault();const r=cityssm.dateToString(new Date),s=Number.parseInt(null!==(t=e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId)&&void 0!==t?t:"",10),a=u.find(e=>e.workOrderMilestoneId===s);bulmaJS.confirm({title:"Complete Milestone",message:`Are you sure you want to complete this milestone?\n ${void 0!==a.workOrderMilestoneDateString&&""!==a.workOrderMilestoneDateString&&a.workOrderMilestoneDateString>r?"
    Note that this milestone is expected to be completed in the future.":""}`,messageIsHtml:!0,contextualColorName:"warning",okButton:{text:"Yes, Complete Milestone",callbackFunction:function(){cityssm.postJSON(`${o.urlPrefix}/workOrders/doCompleteWorkOrderMilestone`,{workOrderId:n,workOrderMilestoneId:s},$)}}})}function x(e){e.preventDefault();const t=e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId;bulmaJS.confirm({title:"Reopen Milestone",message:"Are you sure you want to remove the completion status from this milestone, and reopen it?",contextualColorName:"warning",okButton:{text:"Yes, Reopen Milestone",callbackFunction:function(){cityssm.postJSON(`${o.urlPrefix}/workOrders/doReopenWorkOrderMilestone`,{workOrderId:n,workOrderMilestoneId:t},$)}}})}function E(e){e.preventDefault();const t=e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId;bulmaJS.confirm({title:"Delete Milestone",message:"Are you sure you want to delete this milestone?",contextualColorName:"warning",okButton:{text:"Yes, Delete Milestone",callbackFunction:function(){cityssm.postJSON(`${o.urlPrefix}/workOrders/doDeleteWorkOrderMilestone`,{workOrderMilestoneId:t,workOrderId:n},$)}}})}function D(e){var t;e.preventDefault();const r=Number.parseInt(null!==(t=e.currentTarget.closest(".container--milestone").dataset.workOrderMilestoneId)&&void 0!==t?t:"",10),s=u.find(e=>e.workOrderMilestoneId===r);let a,l;function i(e){e.preventDefault(),cityssm.postJSON(`${o.urlPrefix}/workOrders/doUpdateWorkOrderMilestone`,e.currentTarget,e=>{const t=e;$(t),t.success&&a()})}cityssm.openHtmlModal("workOrder-editMilestone",{onshow(e){var t,o,r,a,i,d;e.querySelector("#milestoneEdit--workOrderId").value=n,e.querySelector("#milestoneEdit--workOrderMilestoneId").value=null!==(o=null===(t=s.workOrderMilestoneId)||void 0===t?void 0:t.toString())&&void 0!==o?o:"";const c=e.querySelector("#milestoneEdit--workOrderMilestoneTypeId");let u=!1;for(const e of exports.workOrderMilestoneTypes){const t=document.createElement("option");t.value=e.workOrderMilestoneTypeId.toString(),t.textContent=e.workOrderMilestoneType,e.workOrderMilestoneTypeId===s.workOrderMilestoneTypeId&&(t.selected=!0,u=!0),c.append(t)}if(!u&&s.workOrderMilestoneTypeId){const e=document.createElement("option");e.value=s.workOrderMilestoneTypeId.toString(),e.textContent=null!==(r=s.workOrderMilestoneType)&&void 0!==r?r:"",e.selected=!0,c.append(e)}(l=e.querySelector("#milestoneEdit--workOrderMilestoneDateString")).value=null!==(a=s.workOrderMilestoneDateString)&&void 0!==a?a:"",s.workOrderMilestoneTime&&(e.querySelector("#milestoneEdit--workOrderMilestoneTimeString").value=null!==(i=s.workOrderMilestoneTimeString)&&void 0!==i?i:""),e.querySelector("#milestoneEdit--workOrderMilestoneDescription").value=null!==(d=s.workOrderMilestoneDescription)&&void 0!==d?d:""},onshown(e,t){var n;a=t,bulmaJS.toggleHtmlClipped(),o.initializeDatePickers(e),null===(n=e.querySelector("form"))||void 0===n||n.addEventListener("submit",i);const r=document.querySelector("#milestoneEdit--conflictingMilestonesPanel");l.addEventListener("change",()=>{C(l.value,r)}),C(l.value,r)},onremoved(){bulmaJS.toggleHtmlClipped()}})}function q(){var e,t,o,n,r,s,a;const l=document.querySelector("#panel--milestones"),i=l.querySelectorAll(".panel-block");for(const e of i)e.remove();for(const i of u){const d=document.createElement("div");d.className="panel-block is-block container--milestone",d.dataset.workOrderMilestoneId=null===(e=i.workOrderMilestoneId)||void 0===e?void 0:e.toString(),d.innerHTML=`
    \n
    \n ${i.workOrderMilestoneCompletionDate?`\n \n `:''}\n
    \n ${i.workOrderMilestoneTypeId?`${cityssm.escapeHTML(null!==(t=i.workOrderMilestoneType)&&void 0!==t?t:"")}
    `:""}\n ${0===i.workOrderMilestoneDate?'(No Set Date)':i.workOrderMilestoneDateString}\n ${i.workOrderMilestoneTime?` ${i.workOrderMilestoneTimePeriodString}`:""}
    \n \n ${cityssm.escapeHTML(null!==(o=i.workOrderMilestoneDescription)&&void 0!==o?o:"")}\n \n
    \n \n
    `,null===(n=d.querySelector(".button--reopenMilestone"))||void 0===n||n.addEventListener("click",x),null===(r=d.querySelector(".button--editMilestone"))||void 0===r||r.addEventListener("click",D),null===(s=d.querySelector(".button--completeMilestone"))||void 0===s||s.addEventListener("click",I),null===(a=d.querySelector(".button--deleteMilestone"))||void 0===a||a.addEventListener("click",E),l.append(d)}bulmaJS.init(l)}delete exports.workOrderComments,null===(S=document.querySelector("#workOrderComments--add"))||void 0===S||S.addEventListener("click",function(){let e;function t(t){t.preventDefault(),cityssm.postJSON(`${o.urlPrefix}/workOrders/doAddWorkOrderComment`,t.currentTarget,t=>{const o=t;o.success&&(f=o.workOrderComments,L(),e())})}cityssm.openHtmlModal("workOrder-addComment",{onshow(e){var r;o.populateAliases(e),e.querySelector("#workOrderCommentAdd--workOrderId").value=n,null===(r=e.querySelector("form"))||void 0===r||r.addEventListener("submit",t)},onshown(t,o){bulmaJS.toggleHtmlClipped(),e=o,t.querySelector("#workOrderCommentAdd--workOrderComment").focus()},onremoved(){bulmaJS.toggleHtmlClipped(),document.querySelector("#workOrderComments--add").focus()}})}),r||L(),r||(u=exports.workOrderMilestones,delete exports.workOrderMilestones,q(),null===(t=document.querySelector("#button--addMilestone"))||void 0===t||t.addEventListener("click",()=>{let e,t,r;function s(n){n&&n.preventDefault();const s=cityssm.dateToString(new Date);function a(){cityssm.postJSON(`${o.urlPrefix}/workOrders/doAddWorkOrderMilestone`,e,e=>{const t=e;$(t),t.success&&r()})}const l=t.value;""!==l&&l{C(t.value,l)}),C(t.value,l)},onremoved(){bulmaJS.toggleHtmlClipped(),document.querySelector("#button--addMilestone").focus()}})}))})(); \ No newline at end of file diff --git a/public/javascripts/workOrderEdit.ts b/public/javascripts/workOrderEdit.ts new file mode 100644 index 00000000..89711d37 --- /dev/null +++ b/public/javascripts/workOrderEdit.ts @@ -0,0 +1,1953 @@ +// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair +/* eslint-disable unicorn/prefer-module */ + +import type { BulmaJS } from '@cityssm/bulma-js/types.js' +import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' + +import type { LOS } from '../../types/globalTypes.js' +import type { + Lot, + LotOccupancy, + LotStatus, + WorkOrderComment, + WorkOrderMilestone, + WorkOrderMilestoneType +} from '../../types/recordTypes.js' + +declare const cityssm: cityssmGlobal +declare const bulmaJS: BulmaJS + +declare const exports: Record +;(() => { + const los = exports.los as LOS + + const workOrderId = ( + document.querySelector('#workOrderEdit--workOrderId') as HTMLInputElement + ).value + + const isCreate = workOrderId === '' + + const workOrderFormElement = document.querySelector( + '#form--workOrderEdit' + ) as HTMLFormElement + + los.initializeDatePickers( + workOrderFormElement + .querySelector('#workOrderEdit--workOrderOpenDateString') + ?.closest('.field') as HTMLElement + ) + los.initializeUnlockFieldButtons(workOrderFormElement) + + function setUnsavedChanges(): void { + los.setUnsavedChanges() + document + .querySelector("button[type='submit'][form='form--workOrderEdit']") + ?.classList.remove('is-light') + } + + function clearUnsavedChanges(): void { + los.clearUnsavedChanges() + document + .querySelector("button[type='submit'][form='form--workOrderEdit']") + ?.classList.add('is-light') + } + + workOrderFormElement.addEventListener('submit', (submitEvent) => { + submitEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/workOrders/${isCreate ? 'doCreateWorkOrder' : 'doUpdateWorkOrder'}`, + submitEvent.currentTarget, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + workOrderId?: number + errorMessage?: string + } + + if (responseJSON.success) { + clearUnsavedChanges() + + if (isCreate) { + window.location.href = los.getWorkOrderURL( + responseJSON.workOrderId, + true + ) + } else { + bulmaJS.alert({ + message: 'Work Order Updated Successfully', + contextualColorName: 'success' + }) + } + } else { + bulmaJS.alert({ + title: 'Error Updating Work Order', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + }) + + const inputElements: NodeListOf< + HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement + > = workOrderFormElement.querySelectorAll('input, select, textarea') + + for (const inputElement of inputElements) { + inputElement.addEventListener('change', setUnsavedChanges) + } + + /* + * Work Order Options + */ + + function doClose(): void { + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doCloseWorkOrder`, + { + workOrderId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + } + + if (responseJSON.success) { + clearUnsavedChanges() + window.location.href = los.getWorkOrderURL(workOrderId) + } else { + bulmaJS.alert({ + title: 'Error Closing Work Order', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doDeleteWorkOrder`, + { + workOrderId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + } + + if (responseJSON.success) { + clearUnsavedChanges() + window.location.href = `${los.urlPrefix}/workOrders` + } else { + bulmaJS.alert({ + title: 'Error Deleting Work Order', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + let workOrderMilestones: WorkOrderMilestone[] + + document + .querySelector('#button--closeWorkOrder') + ?.addEventListener('click', () => { + const hasOpenMilestones = workOrderMilestones.some((milestone) => { + return !milestone.workOrderMilestoneCompletionDate + }) + + if (hasOpenMilestones) { + bulmaJS.alert({ + title: 'Outstanding Milestones', + message: `You cannot close a work order with outstanding milestones. + Either complete the outstanding milestones, or remove them from the work order.`, + contextualColorName: 'warning' + }) + + /* + // Disable closing work orders with open milestones + bulmaJS.confirm({ + title: "Close Work Order with Outstanding Milestones", + message: + "Are you sure you want to close this work order with outstanding milestones?", + contextualColorName: "danger", + okButton: { + text: "Yes, Close Work Order", + callbackFunction: doClose + } + }); + */ + } else { + bulmaJS.confirm({ + title: 'Close Work Order', + message: los.hasUnsavedChanges() + ? 'Are you sure you want to close this work order with unsaved changes?' + : 'Are you sure you want to close this work order?', + contextualColorName: los.hasUnsavedChanges() ? 'warning' : 'info', + okButton: { + text: 'Yes, Close Work Order', + callbackFunction: doClose + } + }) + } + }) + + document + .querySelector('#button--deleteWorkOrder') + ?.addEventListener('click', (clickEvent: Event) => { + clickEvent.preventDefault() + + bulmaJS.confirm({ + title: 'Delete Work Order', + message: 'Are you sure you want to delete this work order?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Work Order', + callbackFunction: doDelete + } + }) + }) + + /** + * Related Lots + */ + if (!isCreate) { + ;(() => { + let workOrderLots = exports.workOrderLots as Lot[] + delete exports.workOrderLots + + let workOrderLotOccupancies = + exports.workOrderLotOccupancies as LotOccupancy[] + delete exports.workOrderLotOccupancies + + function deleteLotOccupancy(clickEvent: Event): void { + const lotOccupancyId = ( + (clickEvent.currentTarget as HTMLElement).closest( + '.container--lotOccupancy' + ) as HTMLElement + ).dataset.lotOccupancyId + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doDeleteWorkOrderLotOccupancy`, + { + workOrderId, + lotOccupancyId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + workOrderLotOccupancies: LotOccupancy[] + } + + if (responseJSON.success) { + workOrderLotOccupancies = responseJSON.workOrderLotOccupancies + renderRelatedLotsAndOccupancies() + } else { + bulmaJS.alert({ + title: 'Error Deleting Relationship', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + bulmaJS.confirm({ + title: `Delete ${los.escapedAliases.Occupancy} Relationship`, + message: `Are you sure you want to remove the relationship to this ${los.escapedAliases.occupancy} record from this work order? Note that the record will remain.`, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Relationship', + callbackFunction: doDelete + } + }) + } + + function addLot( + lotId: number | string, + callbackFunction?: (success: boolean) => void + ): void { + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doAddWorkOrderLot`, + { + workOrderId, + lotId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + workOrderLots: Lot[] + } + + if (responseJSON.success) { + workOrderLots = responseJSON.workOrderLots + renderRelatedLotsAndOccupancies() + } else { + bulmaJS.alert({ + title: `Error Adding ${los.escapedAliases.Lot}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + + if (callbackFunction !== undefined) { + callbackFunction(responseJSON.success) + } + } + ) + } + + function addLotOccupancy( + lotOccupancyId: number | string, + callbackFunction?: (success?: boolean) => void + ): void { + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doAddWorkOrderLotOccupancy`, + { + workOrderId, + lotOccupancyId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + workOrderLotOccupancies: LotOccupancy[] + } + + if (responseJSON.success) { + workOrderLotOccupancies = responseJSON.workOrderLotOccupancies + renderRelatedLotsAndOccupancies() + } else { + bulmaJS.alert({ + title: `Error Adding ${los.escapedAliases.Occupancy}`, + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + + if (callbackFunction !== undefined) { + callbackFunction(responseJSON.success) + } + } + ) + } + + function addLotFromLotOccupancy(clickEvent: Event): void { + const lotId = + (clickEvent.currentTarget as HTMLElement).dataset.lotId ?? '' + addLot(lotId) + } + + function renderRelatedOccupancies(): void { + const occupanciesContainerElement = document.querySelector( + '#container--lotOccupancies' + ) as HTMLElement + + ;( + document.querySelector( + ".tabs a[href='#relatedTab--lotOccupancies'] .tag" + ) as HTMLElement + ).textContent = workOrderLotOccupancies.length.toString() + + if (workOrderLotOccupancies.length === 0) { + // eslint-disable-next-line no-unsanitized/property + occupanciesContainerElement.innerHTML = `
    +

    There are no ${los.escapedAliases.occupancies} associated with this work order.

    +
    ` + + return + } + + // eslint-disable-next-line no-unsanitized/property + occupanciesContainerElement.innerHTML = ` + + + + + + + + + + +
    ${los.escapedAliases.Occupancy} Type${los.escapedAliases.Lot}${los.escapedAliases.OccupancyStartDate}End Date${los.escapedAliases.Occupants}
    ` + + const currentDateString = cityssm.dateToString(new Date()) + + for (const lotOccupancy of workOrderLotOccupancies) { + const rowElement = document.createElement('tr') + rowElement.className = 'container--lotOccupancy' + rowElement.dataset.lotOccupancyId = + lotOccupancy.lotOccupancyId.toString() + + const isActive = !( + lotOccupancy.occupancyEndDate && + lotOccupancy.occupancyEndDateString! < currentDateString + ) + + const hasLotRecord = + lotOccupancy.lotId && + workOrderLots.some((lot) => { + return lotOccupancy.lotId === lot.lotId + }) + + // eslint-disable-next-line no-unsanitized/property + rowElement.innerHTML = ` + ${ + isActive + ? `` + : `` + } + + + ${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')} +
    + #${lotOccupancy.lotOccupancyId} + ` + + if (lotOccupancy.lotId) { + // eslint-disable-next-line no-unsanitized/method + rowElement.insertAdjacentHTML( + 'beforeend', + ` + ${cityssm.escapeHTML(lotOccupancy.lotName ?? '')} + ${ + hasLotRecord + ? '' + : ` ` + } + ` + ) + } else { + // eslint-disable-next-line no-unsanitized/method + rowElement.insertAdjacentHTML( + 'beforeend', + `(No ${los.escapedAliases.Lot})` + ) + } + + let occupantsHTML = '' + + for (const occupant of lotOccupancy.lotOccupancyOccupants!) { + occupantsHTML += `
  • + + + + ${cityssm.escapeHTML(occupant.occupantName ?? '')} + ${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')} +
  • ` + } + + // eslint-disable-next-line no-unsanitized/method + rowElement.insertAdjacentHTML( + 'beforeend', + ` + ${lotOccupancy.occupancyStartDateString} + + ${ + lotOccupancy.occupancyEndDate + ? lotOccupancy.occupancyEndDateString + : '(No End Date)' + } + + ${ + lotOccupancy.lotOccupancyOccupants!.length === 0 + ? `(No ${los.escapedAliases.Occupants})` + : `
      ${occupantsHTML}
    ` + } + + + ` + ) + + rowElement + .querySelector('.button--addLot') + ?.addEventListener('click', addLotFromLotOccupancy) + + rowElement + .querySelector('.button--deleteLotOccupancy') + ?.addEventListener('click', deleteLotOccupancy) + + occupanciesContainerElement.querySelector('tbody')?.append(rowElement) + } + } + + function openEditLotStatus(clickEvent: Event): void { + const lotId = Number.parseInt( + ( + (clickEvent.currentTarget as HTMLElement).closest( + '.container--lot' + ) as HTMLElement + ).dataset.lotId ?? '', + 10 + ) + + const lot = workOrderLots.find((possibleLot) => { + return possibleLot.lotId === lotId + }) as Lot + + let editCloseModalFunction: () => void + + function doUpdateLotStatus(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doUpdateLotStatus`, + submitEvent.currentTarget, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + workOrderLots: Lot[] + } + + if (responseJSON.success) { + workOrderLots = responseJSON.workOrderLots + renderRelatedLotsAndOccupancies() + editCloseModalFunction() + } else { + bulmaJS.alert({ + title: 'Error Deleting Relationship', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + cityssm.openHtmlModal('lot-editLotStatus', { + onshow(modalElement) { + los.populateAliases(modalElement) + ;( + modalElement.querySelector( + '#lotStatusEdit--lotId' + ) as HTMLInputElement + ).value = lotId.toString() + ;( + modalElement.querySelector( + '#lotStatusEdit--lotName' + ) as HTMLInputElement + ).value = lot.lotName ?? '' + + const lotStatusElement = modalElement.querySelector( + '#lotStatusEdit--lotStatusId' + ) as HTMLSelectElement + + let lotStatusFound = false + + for (const lotStatus of exports.lotStatuses as LotStatus[]) { + const optionElement = document.createElement('option') + optionElement.value = lotStatus.lotStatusId.toString() + optionElement.textContent = lotStatus.lotStatus + + if (lotStatus.lotStatusId === lot.lotStatusId) { + lotStatusFound = true + } + + lotStatusElement.append(optionElement) + } + + if (!lotStatusFound && lot.lotStatusId) { + const optionElement = document.createElement('option') + optionElement.value = lot.lotStatusId.toString() + optionElement.textContent = lot.lotStatus ?? '' + lotStatusElement.append(optionElement) + } + + if (lot.lotStatusId) { + lotStatusElement.value = lot.lotStatusId.toString() + } + + // eslint-disable-next-line no-unsanitized/method + modalElement + .querySelector('form') + ?.insertAdjacentHTML( + 'beforeend', + `` + ) + }, + onshown(modalElement, closeModalFunction) { + editCloseModalFunction = closeModalFunction + + bulmaJS.toggleHtmlClipped() + + modalElement + .querySelector('form') + ?.addEventListener('submit', doUpdateLotStatus) + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + } + }) + } + + function deleteLot(clickEvent: Event): void { + const lotId = ( + (clickEvent.currentTarget as HTMLElement).closest( + '.container--lot' + ) as HTMLElement + ).dataset.lotId + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doDeleteWorkOrderLot`, + { + workOrderId, + lotId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + workOrderLots: Lot[] + } + + if (responseJSON.success) { + workOrderLots = responseJSON.workOrderLots + renderRelatedLotsAndOccupancies() + } else { + bulmaJS.alert({ + title: 'Error Deleting Relationship', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + bulmaJS.confirm({ + title: `Delete ${los.escapedAliases.Occupancy} Relationship`, + message: `Are you sure you want to remove the relationship to this ${los.escapedAliases.occupancy} record from this work order? Note that the record will remain.`, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Relationship', + callbackFunction: doDelete + } + }) + } + + function renderRelatedLots(): void { + const lotsContainerElement = document.querySelector( + '#container--lots' + ) as HTMLElement + + ;( + document.querySelector( + ".tabs a[href='#relatedTab--lots'] .tag" + ) as HTMLElement + ).textContent = workOrderLots.length.toString() + + if (workOrderLots.length === 0) { + // eslint-disable-next-line no-unsanitized/property + lotsContainerElement.innerHTML = `
    +

    There are no ${los.escapedAliases.lots} associated with this work order.

    +
    ` + + return + } + + // eslint-disable-next-line no-unsanitized/property + lotsContainerElement.innerHTML = ` + + + + + + + + +
    ${los.escapedAliases.Lot}${los.escapedAliases.Map}${los.escapedAliases.Lot} TypeStatus
    ` + + for (const lot of workOrderLots) { + const rowElement = document.createElement('tr') + rowElement.className = 'container--lot' + + rowElement.dataset.lotId = lot.lotId.toString() + + // eslint-disable-next-line no-unsanitized/property + rowElement.innerHTML = ` + + ${cityssm.escapeHTML(lot.lotName ?? '')} + + + ${cityssm.escapeHTML(lot.mapName ?? '')} + + ${cityssm.escapeHTML(lot.lotType ?? '')} + + ${ + lot.lotStatusId + ? cityssm.escapeHTML(lot.lotStatus ?? '') + : '(No Status)' + } + + + + ` + + rowElement + .querySelector('.button--editLotStatus') + ?.addEventListener('click', openEditLotStatus) + + rowElement + .querySelector('.button--deleteLot') + ?.addEventListener('click', deleteLot) + + lotsContainerElement.querySelector('tbody')?.append(rowElement) + } + } + + function renderRelatedLotsAndOccupancies(): void { + renderRelatedOccupancies() + renderRelatedLots() + } + + renderRelatedLotsAndOccupancies() + + function doAddLotOccupancy(clickEvent: Event): void { + const rowElement = (clickEvent.currentTarget as HTMLElement).closest( + 'tr' + ) as HTMLTableRowElement + + const lotOccupancyId = rowElement.dataset.lotOccupancyId ?? '' + + addLotOccupancy(lotOccupancyId, (success) => { + if (success) { + rowElement.remove() + } + }) + } + + document + .querySelector('#button--addLotOccupancy') + ?.addEventListener('click', () => { + let searchFormElement: HTMLFormElement + let searchResultsContainerElement: HTMLElement + + function doSearch(event?: Event): void { + if (event) { + event.preventDefault() + } + + // eslint-disable-next-line no-unsanitized/property + searchResultsContainerElement.innerHTML = + los.getLoadingParagraphHTML('Searching...') + + cityssm.postJSON( + `${los.urlPrefix}/lotOccupancies/doSearchLotOccupancies`, + searchFormElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + lotOccupancies: LotOccupancy[] + } + + if (responseJSON.lotOccupancies.length === 0) { + searchResultsContainerElement.innerHTML = `
    +

    There are no records that meet the search criteria.

    +
    ` + + return + } + + // eslint-disable-next-line no-unsanitized/property + searchResultsContainerElement.innerHTML = ` + + + + + + + + + +
    ${los.escapedAliases.Occupancy} Type${los.escapedAliases.Lot}${los.escapedAliases.OccupancyStartDate}End Date${los.escapedAliases.Occupants}
    ` + + for (const lotOccupancy of responseJSON.lotOccupancies) { + const rowElement = document.createElement('tr') + rowElement.className = 'container--lotOccupancy' + rowElement.dataset.lotOccupancyId = + lotOccupancy.lotOccupancyId.toString() + + rowElement.innerHTML = ` + + + + ${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')} + ` + + if (lotOccupancy.lotId) { + rowElement.insertAdjacentHTML( + 'beforeend', + `${cityssm.escapeHTML(lotOccupancy.lotName ?? '')}` + ) + } else { + // eslint-disable-next-line no-unsanitized/method + rowElement.insertAdjacentHTML( + 'beforeend', + `(No ${los.escapedAliases.Lot})` + ) + } + + // eslint-disable-next-line no-unsanitized/method + rowElement.insertAdjacentHTML( + 'beforeend', + ` + ${lotOccupancy.occupancyStartDateString} + + ${ + lotOccupancy.occupancyEndDate + ? lotOccupancy.occupancyEndDateString + : '(No End Date)' + } + + ${ + lotOccupancy.lotOccupancyOccupants!.length === 0 + ? ` + (No ${cityssm.escapeHTML( + los.escapedAliases.Occupants + )}) + ` + : cityssm.escapeHTML( + `${lotOccupancy.lotOccupancyOccupants![0].occupantName} + ${ + lotOccupancy.lotOccupancyOccupants![0] + .occupantFamilyName + }` + ) + + (lotOccupancy.lotOccupancyOccupants!.length > 1 + ? ` plus + ${( + lotOccupancy.lotOccupancyOccupants!.length - 1 + ).toString()}` + : '') + }` + ) + + rowElement + .querySelector('.button--addLotOccupancy') + ?.addEventListener('click', doAddLotOccupancy) + + searchResultsContainerElement + .querySelector('tbody') + ?.append(rowElement) + } + } + ) + } + + cityssm.openHtmlModal('workOrder-addLotOccupancy', { + onshow(modalElement) { + los.populateAliases(modalElement) + + searchFormElement = modalElement.querySelector( + 'form' + ) as HTMLFormElement + + searchResultsContainerElement = modalElement.querySelector( + '#resultsContainer--lotOccupancyAdd' + ) as HTMLElement + ;( + modalElement.querySelector( + '#lotOccupancySearch--notWorkOrderId' + ) as HTMLInputElement + ).value = workOrderId + ;( + modalElement.querySelector( + '#lotOccupancySearch--occupancyEffectiveDateString' + ) as HTMLInputElement + ).value = ( + document.querySelector( + '#workOrderEdit--workOrderOpenDateString' + ) as HTMLInputElement + ).value + + doSearch() + }, + onshown(modalElement) { + bulmaJS.toggleHtmlClipped() + + const occupantNameElement = modalElement.querySelector( + '#lotOccupancySearch--occupantName' + ) as HTMLInputElement + + occupantNameElement.addEventListener('change', doSearch) + occupantNameElement.focus() + ;( + modalElement.querySelector( + '#lotOccupancySearch--lotName' + ) as HTMLInputElement + ).addEventListener('change', doSearch) + + searchFormElement.addEventListener('submit', doSearch) + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + ;( + document.querySelector( + '#button--addLotOccupancy' + ) as HTMLButtonElement + ).focus() + } + }) + }) + + function doAddLot(clickEvent: Event): void { + const rowElement = (clickEvent.currentTarget as HTMLElement).closest( + 'tr' + ) as HTMLTableRowElement + + const lotId = rowElement.dataset.lotId ?? '' + + addLot(lotId, (success) => { + if (success) { + rowElement.remove() + } + }) + } + + document + .querySelector('#button--addLot') + ?.addEventListener('click', () => { + let searchFormElement: HTMLFormElement + let searchResultsContainerElement: HTMLElement + + function doSearch(event?: Event): void { + if (event) { + event.preventDefault() + } + + // eslint-disable-next-line no-unsanitized/property + searchResultsContainerElement.innerHTML = + los.getLoadingParagraphHTML('Searching...') + + cityssm.postJSON( + `${los.urlPrefix}/lots/doSearchLots`, + searchFormElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { lots: Lot[] } + + if (responseJSON.lots.length === 0) { + searchResultsContainerElement.innerHTML = `
    +

    There are no records that meet the search criteria.

    +
    ` + + return + } + + // eslint-disable-next-line no-unsanitized/property + searchResultsContainerElement.innerHTML = ` + + + + + + + + +
    ${los.escapedAliases.Lot}${los.escapedAliases.Map}${los.escapedAliases.Lot} TypeStatus
    ` + + for (const lot of responseJSON.lots) { + const rowElement = document.createElement('tr') + rowElement.className = 'container--lot' + rowElement.dataset.lotId = lot.lotId.toString() + + rowElement.innerHTML = ` + + + ${cityssm.escapeHTML(lot.lotName ?? '')} + + ${cityssm.escapeHTML(lot.mapName ?? '')} + + ${cityssm.escapeHTML(lot.lotType ?? '')} + + ${cityssm.escapeHTML(lot.lotStatus ?? '')} + ` + + rowElement + .querySelector('.button--addLot') + ?.addEventListener('click', doAddLot) + + searchResultsContainerElement + .querySelector('tbody') + ?.append(rowElement) + } + } + ) + } + + cityssm.openHtmlModal('workOrder-addLot', { + onshow(modalElement) { + los.populateAliases(modalElement) + + searchFormElement = modalElement.querySelector( + 'form' + ) as HTMLFormElement + + searchResultsContainerElement = modalElement.querySelector( + '#resultsContainer--lotAdd' + ) as HTMLElement + ;( + modalElement.querySelector( + '#lotSearch--notWorkOrderId' + ) as HTMLInputElement + ).value = workOrderId + + const lotStatusElement = modalElement.querySelector( + '#lotSearch--lotStatusId' + ) as HTMLSelectElement + + for (const lotStatus of exports.lotStatuses as LotStatus[]) { + const optionElement = document.createElement('option') + optionElement.value = lotStatus.lotStatusId.toString() + optionElement.textContent = lotStatus.lotStatus + lotStatusElement.append(optionElement) + } + + doSearch() + }, + onshown(modalElement) { + bulmaJS.toggleHtmlClipped() + + const lotNameElement = modalElement.querySelector( + '#lotSearch--lotName' + ) as HTMLInputElement + + lotNameElement.addEventListener('change', doSearch) + lotNameElement.focus() + + modalElement + .querySelector('#lotSearch--lotStatusId') + ?.addEventListener('change', doSearch) + + searchFormElement.addEventListener('submit', doSearch) + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + ;( + document.querySelector('#button--addLot') as HTMLButtonElement + ).focus() + } + }) + }) + })() + } + + /** + * Comments + */ + ;(() => { + let workOrderComments = exports.workOrderComments as WorkOrderComment[] + delete exports.workOrderComments + + function openEditWorkOrderComment(clickEvent: Event): void { + const workOrderCommentId = Number.parseInt( + (clickEvent.currentTarget as HTMLElement).closest('tr')?.dataset + .workOrderCommentId ?? '', + 10 + ) + + const workOrderComment = workOrderComments.find((currentComment) => { + return currentComment.workOrderCommentId === workOrderCommentId + }) as WorkOrderComment + + let editFormElement: HTMLFormElement + let editCloseModalFunction: () => void + + function editComment(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doUpdateWorkOrderComment`, + editFormElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + workOrderComments: WorkOrderComment[] + } + + if (responseJSON.success) { + workOrderComments = responseJSON.workOrderComments + editCloseModalFunction() + renderWorkOrderComments() + } else { + bulmaJS.alert({ + title: 'Error Updating Comment', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + cityssm.openHtmlModal('workOrder-editComment', { + onshow(modalElement) { + ;( + modalElement.querySelector( + '#workOrderCommentEdit--workOrderId' + ) as HTMLInputElement + ).value = workOrderId + ;( + modalElement.querySelector( + '#workOrderCommentEdit--workOrderCommentId' + ) as HTMLInputElement + ).value = workOrderCommentId.toString() + ;( + modalElement.querySelector( + '#workOrderCommentEdit--workOrderComment' + ) as HTMLInputElement + ).value = workOrderComment.workOrderComment ?? '' + + const workOrderCommentDateStringElement = modalElement.querySelector( + '#workOrderCommentEdit--workOrderCommentDateString' + ) as HTMLInputElement + + workOrderCommentDateStringElement.value = + workOrderComment.workOrderCommentDateString ?? '' + + const currentDateString = cityssm.dateToString(new Date()) + + workOrderCommentDateStringElement.max = + workOrderComment.workOrderCommentDateString! <= currentDateString + ? currentDateString + : workOrderComment.workOrderCommentDateString ?? '' + ;( + modalElement.querySelector( + '#workOrderCommentEdit--workOrderCommentTimeString' + ) as HTMLInputElement + ).value = workOrderComment.workOrderCommentTimeString ?? '' + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped() + + los.initializeDatePickers(modalElement) + ;( + modalElement.querySelector( + '#workOrderCommentEdit--workOrderComment' + ) as HTMLTextAreaElement + ).focus() + + editFormElement = modalElement.querySelector( + 'form' + ) as HTMLFormElement + editFormElement.addEventListener('submit', editComment) + + editCloseModalFunction = closeModalFunction + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + } + }) + } + + function deleteWorkOrderComment(clickEvent: Event): void { + const workOrderCommentId = Number.parseInt( + (clickEvent.currentTarget as HTMLElement).closest('tr')?.dataset + .workOrderCommentId ?? '', + 10 + ) + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doDeleteWorkOrderComment`, + { + workOrderId, + workOrderCommentId + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + workOrderComments: WorkOrderComment[] + } + + if (responseJSON.success) { + workOrderComments = responseJSON.workOrderComments + renderWorkOrderComments() + } else { + bulmaJS.alert({ + title: 'Error Removing Comment', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + ) + } + + bulmaJS.confirm({ + title: 'Remove Comment?', + message: 'Are you sure you want to remove this comment?', + okButton: { + text: 'Yes, Remove Comment', + callbackFunction: doDelete + }, + contextualColorName: 'warning' + }) + } + + function renderWorkOrderComments(): void { + const containerElement = document.querySelector( + '#container--workOrderComments' + ) as HTMLElement + + if (workOrderComments.length === 0) { + containerElement.innerHTML = `
    +

    There are no comments to display.

    +
    ` + return + } + + const tableElement = document.createElement('table') + tableElement.className = 'table is-fullwidth is-striped is-hoverable' + tableElement.innerHTML = ` + Commentor + Comment Date + Comment + Options` + + for (const workOrderComment of workOrderComments) { + const tableRowElement = document.createElement('tr') + + tableRowElement.dataset.workOrderCommentId = + workOrderComment.workOrderCommentId?.toString() + + // eslint-disable-next-line no-unsanitized/property + tableRowElement.innerHTML = ` + ${cityssm.escapeHTML(workOrderComment.recordCreate_userName ?? '')} + + ${workOrderComment.workOrderCommentDateString} + ${ + workOrderComment.workOrderCommentTime === 0 + ? '' + : workOrderComment.workOrderCommentTimePeriodString + } + + ${cityssm.escapeHTML(workOrderComment.workOrderComment ?? '')} + +
    + + +
    + ` + + tableRowElement + .querySelector('.button--edit') + ?.addEventListener('click', openEditWorkOrderComment) + + tableRowElement + .querySelector('.button--delete') + ?.addEventListener('click', deleteWorkOrderComment) + + tableElement.querySelector('tbody')?.append(tableRowElement) + } + + containerElement.innerHTML = '' + containerElement.append(tableElement) + } + + function openAddCommentModal(): void { + let addCommentCloseModalFunction: () => void + + function doAddComment(formEvent: SubmitEvent): void { + formEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doAddWorkOrderComment`, + formEvent.currentTarget, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + workOrderComments: WorkOrderComment[] + } + + if (responseJSON.success) { + workOrderComments = responseJSON.workOrderComments + renderWorkOrderComments() + addCommentCloseModalFunction() + } + } + ) + } + + cityssm.openHtmlModal('workOrder-addComment', { + onshow(modalElement) { + los.populateAliases(modalElement) + ;( + modalElement.querySelector( + '#workOrderCommentAdd--workOrderId' + ) as HTMLInputElement + ).value = workOrderId + + modalElement + .querySelector('form') + ?.addEventListener('submit', doAddComment) + }, + onshown(modalElement, closeModalFunction) { + bulmaJS.toggleHtmlClipped() + addCommentCloseModalFunction = closeModalFunction + ;( + modalElement.querySelector( + '#workOrderCommentAdd--workOrderComment' + ) as HTMLTextAreaElement + ).focus() + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + ;( + document.querySelector( + '#workOrderComments--add' + ) as HTMLButtonElement + ).focus() + } + }) + } + + document + .querySelector('#workOrderComments--add') + ?.addEventListener('click', openAddCommentModal) + + if (!isCreate) { + renderWorkOrderComments() + } + })() + + /* + * Milestones + */ + + function clearPanelBlockElements(panelElement: HTMLElement): void { + for (const panelBlockElement of panelElement.querySelectorAll( + '.panel-block' + )) { + panelBlockElement.remove() + } + } + + function refreshConflictingMilestones( + workOrderMilestoneDateString: string, + targetPanelElement: HTMLElement + ): void { + // Clear panel-block elements + clearPanelBlockElements(targetPanelElement) + + // eslint-disable-next-line no-unsanitized/method + targetPanelElement.insertAdjacentHTML( + 'beforeend', + `
    + ${los.getLoadingParagraphHTML('Loading conflicting milestones...')} +
    ` + ) + + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doGetWorkOrderMilestones`, + { + workOrderMilestoneDateFilter: 'date', + workOrderMilestoneDateString + }, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + workOrderMilestones: WorkOrderMilestone[] + } + + const workOrderMilestones = responseJSON.workOrderMilestones.filter( + (possibleMilestone) => { + return possibleMilestone.workOrderId.toString() !== workOrderId + } + ) + + clearPanelBlockElements(targetPanelElement) + + for (const milestone of workOrderMilestones) { + targetPanelElement.insertAdjacentHTML( + 'beforeend', + `
    +
    +
    + ${cityssm.escapeHTML(milestone.workOrderMilestoneTime === 0 ? 'No Time' : milestone.workOrderMilestoneTimePeriodString ?? '')}
    + ${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')} +
    +
    + ${cityssm.escapeHTML(milestone.workOrderNumber ?? '')}
    + + ${cityssm.escapeHTML(milestone.workOrderDescription ?? '')} + +
    +
    +
    ` + ) + } + + if (workOrderMilestones.length === 0) { + targetPanelElement.insertAdjacentHTML( + 'beforeend', + `
    +
    +

    + There are no milestones on other work orders scheduled for + ${cityssm.escapeHTML(workOrderMilestoneDateString)}. +

    +
    +
    ` + ) + } + } + ) + } + + function processMilestoneResponse(rawResponseJSON: unknown): void { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + workOrderMilestones: WorkOrderMilestone[] + } + + if (responseJSON.success) { + workOrderMilestones = responseJSON.workOrderMilestones + renderMilestones() + } else { + bulmaJS.alert({ + title: 'Error Reopening Milestone', + message: responseJSON.errorMessage ?? '', + contextualColorName: 'danger' + }) + } + } + + function completeMilestone(clickEvent: Event): void { + clickEvent.preventDefault() + + const currentDateString = cityssm.dateToString(new Date()) + + const workOrderMilestoneId = Number.parseInt( + ( + (clickEvent.currentTarget as HTMLElement).closest( + '.container--milestone' + ) as HTMLElement + ).dataset.workOrderMilestoneId ?? '', + 10 + ) + + const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { + return currentMilestone.workOrderMilestoneId === workOrderMilestoneId + }) as WorkOrderMilestone + + function doComplete(): void { + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doCompleteWorkOrderMilestone`, + { + workOrderId, + workOrderMilestoneId + }, + processMilestoneResponse + ) + } + + bulmaJS.confirm({ + title: 'Complete Milestone', + message: `Are you sure you want to complete this milestone? + ${ + workOrderMilestone.workOrderMilestoneDateString !== undefined && + workOrderMilestone.workOrderMilestoneDateString !== '' && + workOrderMilestone.workOrderMilestoneDateString > currentDateString + ? '
    Note that this milestone is expected to be completed in the future.' + : '' + }`, + messageIsHtml: true, + contextualColorName: 'warning', + okButton: { + text: 'Yes, Complete Milestone', + callbackFunction: doComplete + } + }) + } + + function reopenMilestone(clickEvent: Event): void { + clickEvent.preventDefault() + + const workOrderMilestoneId = ( + (clickEvent.currentTarget as HTMLElement).closest( + '.container--milestone' + ) as HTMLElement + ).dataset.workOrderMilestoneId + + function doReopen(): void { + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doReopenWorkOrderMilestone`, + { + workOrderId, + workOrderMilestoneId + }, + processMilestoneResponse + ) + } + + bulmaJS.confirm({ + title: 'Reopen Milestone', + message: + 'Are you sure you want to remove the completion status from this milestone, and reopen it?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Reopen Milestone', + callbackFunction: doReopen + } + }) + } + + function deleteMilestone(clickEvent: Event): void { + clickEvent.preventDefault() + + const workOrderMilestoneId = ( + (clickEvent.currentTarget as HTMLElement).closest( + '.container--milestone' + ) as HTMLElement + ).dataset.workOrderMilestoneId + + function doDelete(): void { + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doDeleteWorkOrderMilestone`, + { + workOrderMilestoneId, + workOrderId + }, + processMilestoneResponse + ) + } + + bulmaJS.confirm({ + title: 'Delete Milestone', + message: 'Are you sure you want to delete this milestone?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Delete Milestone', + callbackFunction: doDelete + } + }) + } + + function editMilestone(clickEvent: Event): void { + clickEvent.preventDefault() + + const workOrderMilestoneId = Number.parseInt( + ( + (clickEvent.currentTarget as HTMLElement).closest( + '.container--milestone' + ) as HTMLElement + ).dataset.workOrderMilestoneId ?? '', + 10 + ) + + const workOrderMilestone = workOrderMilestones.find((currentMilestone) => { + return currentMilestone.workOrderMilestoneId === workOrderMilestoneId + }) as WorkOrderMilestone + + let editCloseModalFunction: () => void + let workOrderMilestoneDateStringElement: HTMLInputElement + + function doEdit(submitEvent: SubmitEvent): void { + submitEvent.preventDefault() + + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doUpdateWorkOrderMilestone`, + submitEvent.currentTarget, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + workOrderMilestones?: WorkOrderMilestone[] + } + + processMilestoneResponse(responseJSON) + if (responseJSON.success) { + editCloseModalFunction() + } + } + ) + } + + cityssm.openHtmlModal('workOrder-editMilestone', { + onshow(modalElement) { + ;( + modalElement.querySelector( + '#milestoneEdit--workOrderId' + ) as HTMLInputElement + ).value = workOrderId + ;( + modalElement.querySelector( + '#milestoneEdit--workOrderMilestoneId' + ) as HTMLInputElement + ).value = workOrderMilestone.workOrderMilestoneId?.toString() ?? '' + + const milestoneTypeElement = modalElement.querySelector( + '#milestoneEdit--workOrderMilestoneTypeId' + ) as HTMLSelectElement + + let milestoneTypeFound = false + + for (const milestoneType of exports.workOrderMilestoneTypes as WorkOrderMilestoneType[]) { + const optionElement = document.createElement('option') + + optionElement.value = + milestoneType.workOrderMilestoneTypeId.toString() + optionElement.textContent = milestoneType.workOrderMilestoneType + + if ( + milestoneType.workOrderMilestoneTypeId === + workOrderMilestone.workOrderMilestoneTypeId + ) { + optionElement.selected = true + milestoneTypeFound = true + } + + milestoneTypeElement.append(optionElement) + } + + if ( + !milestoneTypeFound && + workOrderMilestone.workOrderMilestoneTypeId + ) { + const optionElement = document.createElement('option') + + optionElement.value = + workOrderMilestone.workOrderMilestoneTypeId.toString() + + optionElement.textContent = + workOrderMilestone.workOrderMilestoneType ?? '' + + optionElement.selected = true + + milestoneTypeElement.append(optionElement) + } + + workOrderMilestoneDateStringElement = modalElement.querySelector( + '#milestoneEdit--workOrderMilestoneDateString' + ) as HTMLInputElement + + workOrderMilestoneDateStringElement.value = + workOrderMilestone.workOrderMilestoneDateString ?? '' + + if (workOrderMilestone.workOrderMilestoneTime) { + ;( + modalElement.querySelector( + '#milestoneEdit--workOrderMilestoneTimeString' + ) as HTMLInputElement + ).value = workOrderMilestone.workOrderMilestoneTimeString ?? '' + } + + ;( + modalElement.querySelector( + '#milestoneEdit--workOrderMilestoneDescription' + ) as HTMLTextAreaElement + ).value = workOrderMilestone.workOrderMilestoneDescription ?? '' + }, + onshown(modalElement, closeModalFunction) { + editCloseModalFunction = closeModalFunction + + bulmaJS.toggleHtmlClipped() + + los.initializeDatePickers(modalElement) + // los.initializeTimePickers(modalElement); + modalElement.querySelector('form')?.addEventListener('submit', doEdit) + + const conflictingMilestonePanelElement = document.querySelector( + '#milestoneEdit--conflictingMilestonesPanel' + ) as HTMLElement + + workOrderMilestoneDateStringElement.addEventListener('change', () => { + refreshConflictingMilestones( + workOrderMilestoneDateStringElement.value, + conflictingMilestonePanelElement + ) + }) + + refreshConflictingMilestones( + workOrderMilestoneDateStringElement.value, + conflictingMilestonePanelElement + ) + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + } + }) + } + + function renderMilestones(): void { + // Clear milestones panel + const milestonesPanelElement = document.querySelector( + '#panel--milestones' + ) as HTMLElement + + const panelBlockElementsToDelete = + milestonesPanelElement.querySelectorAll('.panel-block') + + for (const panelBlockToDelete of panelBlockElementsToDelete) { + panelBlockToDelete.remove() + } + + for (const milestone of workOrderMilestones) { + const panelBlockElement = document.createElement('div') + panelBlockElement.className = 'panel-block is-block container--milestone' + + panelBlockElement.dataset.workOrderMilestoneId = + milestone.workOrderMilestoneId?.toString() + + // eslint-disable-next-line no-unsanitized/property + panelBlockElement.innerHTML = `
    +
    + ${ + milestone.workOrderMilestoneCompletionDate + ? ` + + ` + : `` + } +
    + ${ + milestone.workOrderMilestoneTypeId + ? `${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')}
    ` + : '' + } + ${ + milestone.workOrderMilestoneDate === 0 + ? '(No Set Date)' + : milestone.workOrderMilestoneDateString + } + ${ + milestone.workOrderMilestoneTime + ? ` ${milestone.workOrderMilestoneTimePeriodString}` + : '' + }
    + + ${cityssm.escapeHTML(milestone.workOrderMilestoneDescription ?? '')} + +
    + +
    ` + + panelBlockElement + .querySelector('.button--reopenMilestone') + ?.addEventListener('click', reopenMilestone) + panelBlockElement + .querySelector('.button--editMilestone') + ?.addEventListener('click', editMilestone) + + panelBlockElement + .querySelector('.button--completeMilestone') + ?.addEventListener('click', completeMilestone) + + panelBlockElement + .querySelector('.button--deleteMilestone') + ?.addEventListener('click', deleteMilestone) + + milestonesPanelElement.append(panelBlockElement) + } + + bulmaJS.init(milestonesPanelElement) + } + + if (!isCreate) { + workOrderMilestones = exports.workOrderMilestones as WorkOrderMilestone[] + delete exports.workOrderMilestones + + renderMilestones() + + document + .querySelector('#button--addMilestone') + ?.addEventListener('click', () => { + let addFormElement: HTMLFormElement + let workOrderMilestoneDateStringElement: HTMLInputElement + let addCloseModalFunction: () => void + + function doAdd(submitEvent: SubmitEvent): void { + if (submitEvent) { + submitEvent.preventDefault() + } + + const currentDateString = cityssm.dateToString(new Date()) + + function _doAdd(): void { + cityssm.postJSON( + `${los.urlPrefix}/workOrders/doAddWorkOrderMilestone`, + addFormElement, + (rawResponseJSON) => { + const responseJSON = rawResponseJSON as { + success: boolean + errorMessage?: string + workOrderMilestones?: WorkOrderMilestone[] + } + + processMilestoneResponse(responseJSON) + + if (responseJSON.success) { + addCloseModalFunction() + } + } + ) + } + + const milestoneDateString = workOrderMilestoneDateStringElement.value + + if ( + milestoneDateString !== '' && + milestoneDateString < currentDateString + ) { + bulmaJS.confirm({ + title: 'Milestone Date in the Past', + message: + 'Are you sure you want to create a milestone with a date in the past?', + contextualColorName: 'warning', + okButton: { + text: 'Yes, Create a Past Milestone', + callbackFunction: _doAdd + } + }) + } else { + _doAdd() + } + } + + cityssm.openHtmlModal('workOrder-addMilestone', { + onshow(modalElement) { + ;( + modalElement.querySelector( + '#milestoneAdd--workOrderId' + ) as HTMLInputElement + ).value = workOrderId + + const milestoneTypeElement = modalElement.querySelector( + '#milestoneAdd--workOrderMilestoneTypeId' + ) as HTMLSelectElement + + for (const milestoneType of exports.workOrderMilestoneTypes as WorkOrderMilestoneType[]) { + const optionElement = document.createElement('option') + + optionElement.value = + milestoneType.workOrderMilestoneTypeId.toString() + optionElement.textContent = milestoneType.workOrderMilestoneType + + milestoneTypeElement.append(optionElement) + } + + workOrderMilestoneDateStringElement = modalElement.querySelector( + '#milestoneAdd--workOrderMilestoneDateString' + ) as HTMLInputElement + + workOrderMilestoneDateStringElement.valueAsDate = new Date() + }, + onshown(modalElement, closeModalFunction) { + addCloseModalFunction = closeModalFunction + + los.initializeDatePickers(modalElement) + // los.initializeTimePickers(modalElement); + + bulmaJS.toggleHtmlClipped() + ;( + modalElement.querySelector( + '#milestoneAdd--workOrderMilestoneTypeId' + ) as HTMLSelectElement + ).focus() + + addFormElement = modalElement.querySelector( + 'form' + ) as HTMLFormElement + addFormElement.addEventListener('submit', doAdd) + + const conflictingMilestonePanelElement = document.querySelector( + '#milestoneAdd--conflictingMilestonesPanel' + ) as HTMLElement + + workOrderMilestoneDateStringElement.addEventListener( + 'change', + () => { + refreshConflictingMilestones( + workOrderMilestoneDateStringElement.value, + conflictingMilestonePanelElement + ) + } + ) + + refreshConflictingMilestones( + workOrderMilestoneDateStringElement.value, + conflictingMilestonePanelElement + ) + }, + onremoved() { + bulmaJS.toggleHtmlClipped() + ;( + document.querySelector( + '#button--addMilestone' + ) as HTMLButtonElement + ).focus() + } + }) + }) + } +})() diff --git a/public-typescript/workOrderMilestoneCalendar.d.ts b/public/javascripts/workOrderMilestoneCalendar.d.ts similarity index 100% rename from public-typescript/workOrderMilestoneCalendar.d.ts rename to public/javascripts/workOrderMilestoneCalendar.d.ts diff --git a/public-typescript/workOrderMilestoneCalendar.js b/public/javascripts/workOrderMilestoneCalendar.js similarity index 100% rename from public-typescript/workOrderMilestoneCalendar.js rename to public/javascripts/workOrderMilestoneCalendar.js diff --git a/public/javascripts/workOrderMilestoneCalendar.min.js b/public/javascripts/workOrderMilestoneCalendar.min.js deleted file mode 100644 index 1dd9c120..00000000 --- a/public/javascripts/workOrderMilestoneCalendar.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,s=document.querySelector("#form--searchFilters"),n=s.querySelector("#searchFilter--workOrderMilestoneDateFilter"),r=s.querySelector("#searchFilter--workOrderMilestoneDateString"),a=document.querySelector("#container--milestoneCalendar");function i(n){n&&n.preventDefault(),a.innerHTML=e.getLoadingParagraphHTML("Loading Milestones..."),cityssm.postJSON(`${e.urlPrefix}/workOrders/doGetWorkOrderMilestones`,s,s=>{!function(s){var n,r,i,t,l,o,c,d,p,u,m,v,M,f,O;if(0===s.length)return void(a.innerHTML='
    \n

    There are no milestones that meet the search criteria.

    \n
    ');a.innerHTML="";const k=cityssm.dateToString(new Date);let g,w="x";for(const y of s){w!==y.workOrderMilestoneDateString&&(g&&a.append(g),(g=document.createElement("div")).className="panel",g.innerHTML=`

    \n ${cityssm.escapeHTML(0===y.workOrderMilestoneDate?"No Set Date":null!==(n=y.workOrderMilestoneDateString)&&void 0!==n?n:"")}\n

    `,w=null!==(r=y.workOrderMilestoneDateString)&&void 0!==r?r:"");const s=document.createElement("div");s.className="panel-block is-block",!y.workOrderMilestoneCompletionDate&&""!==y.workOrderMilestoneDateString&&y.workOrderMilestoneDateString\n \n \n \n ${cityssm.escapeHTML(null!==(l=s.lotName)&&void 0!==l?l:"")}\n `;for(const s of null!==(o=y.workOrderLotOccupancies)&&void 0!==o?o:[])for(const n of null!==(c=s.lotOccupancyOccupants)&&void 0!==c?c:[])L+=`
  • \n \n \n \n ${cityssm.escapeHTML(null!==(p=n.occupantName)&&void 0!==p?p:"")}\n ${cityssm.escapeHTML(null!==(u=n.occupantFamilyName)&&void 0!==u?u:"")}\n
  • `;s.innerHTML=`
    \n
    \n \n ${y.workOrderMilestoneCompletionDate?'':''}\n \n
    \n ${0===y.workOrderMilestoneTime?"":`${y.workOrderMilestoneTimePeriodString}
    `}\n ${y.workOrderMilestoneTypeId?`${cityssm.escapeHTML(null!==(m=y.workOrderMilestoneType)&&void 0!==m?m:"")}
    `:""}\n \n ${cityssm.escapeHTML(null!==(v=y.workOrderMilestoneDescription)&&void 0!==v?v:"")}\n \n
    \n \n \n ${cityssm.escapeHTML(null!==(f=y.workOrderNumber)&&void 0!==f?f:"")}\n
    \n ${cityssm.escapeHTML(null!==(O=y.workOrderDescription)&&void 0!==O?O:"")}\n
    \n ${""===L?"":`
      ${L}
    `}
    `,g.append(s)}a.append(g)}(s.workOrderMilestones)})}n.addEventListener("change",()=>{r.closest("fieldset").disabled="date"!==n.value,i()}),e.initializeDatePickers(s),r.addEventListener("change",i),s.addEventListener("submit",i),i()})(); \ No newline at end of file diff --git a/public-typescript/workOrderMilestoneCalendar.ts b/public/javascripts/workOrderMilestoneCalendar.ts similarity index 98% rename from public-typescript/workOrderMilestoneCalendar.ts rename to public/javascripts/workOrderMilestoneCalendar.ts index 20ffd078..be836365 100644 --- a/public-typescript/workOrderMilestoneCalendar.ts +++ b/public/javascripts/workOrderMilestoneCalendar.ts @@ -3,8 +3,8 @@ import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' -import type { LOS } from '../types/globalTypes.js' -import type { WorkOrderMilestone } from '../types/recordTypes.js' +import type { LOS } from '../../types/globalTypes.js' +import type { WorkOrderMilestone } from '../../types/recordTypes.js' declare const cityssm: cityssmGlobal diff --git a/public-typescript/workOrderOutlook.d.ts b/public/javascripts/workOrderOutlook.d.ts similarity index 100% rename from public-typescript/workOrderOutlook.d.ts rename to public/javascripts/workOrderOutlook.d.ts diff --git a/public-typescript/workOrderOutlook.js b/public/javascripts/workOrderOutlook.js similarity index 100% rename from public-typescript/workOrderOutlook.js rename to public/javascripts/workOrderOutlook.js diff --git a/public/javascripts/workOrderOutlook.min.js b/public/javascripts/workOrderOutlook.min.js deleted file mode 100644 index 1a814e23..00000000 --- a/public/javascripts/workOrderOutlook.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=document.querySelector("#icsFilters--workOrderTypeIds"),r=document.querySelector("#icsFilters--workOrderMilestoneTypeIds"),s=document.querySelector("#icsFilters--calendarURL");function o(){let o=`${window.location.href.slice(0,Math.max(0,window.location.href.indexOf(window.location.pathname)+1))+e.urlPrefix}api/${e.apiKey}/milestoneICS/?`;if(!t.disabled&&t.selectedOptions.length>0){o+="workOrderTypeIds=";for(const e of t.selectedOptions)o+=`${e.value},`;o=`${o.slice(0,-1)}&`}if(!r.disabled&&r.selectedOptions.length>0){o+="workOrderMilestoneTypeIds=";for(const e of r.selectedOptions)o+=`${e.value},`;o=`${o.slice(0,-1)}&`}s.value=o.slice(0,-1)}document.querySelector("#icsFilters--workOrderTypeIds-all").addEventListener("change",e=>{t.disabled=e.currentTarget.checked}),document.querySelector("#icsFilters--workOrderMilestoneTypeIds-all").addEventListener("change",e=>{r.disabled=e.currentTarget.checked});const c=document.querySelector("#panel--icsFilters").querySelectorAll("input, select");for(const e of c)e.addEventListener("change",o);o(),s.addEventListener("click",()=>{s.focus(),s.select()})})(); \ No newline at end of file diff --git a/public-typescript/workOrderOutlook.ts b/public/javascripts/workOrderOutlook.ts similarity index 97% rename from public-typescript/workOrderOutlook.ts rename to public/javascripts/workOrderOutlook.ts index a52fb67b..a7ce818c 100644 --- a/public-typescript/workOrderOutlook.ts +++ b/public/javascripts/workOrderOutlook.ts @@ -1,7 +1,7 @@ // eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair /* eslint-disable unicorn/prefer-module */ -import type { LOS } from '../types/globalTypes.js' +import type { LOS } from '../../types/globalTypes.js' declare const exports: Record ;(() => { diff --git a/public-typescript/workOrderSearch.d.ts b/public/javascripts/workOrderSearch.d.ts similarity index 100% rename from public-typescript/workOrderSearch.d.ts rename to public/javascripts/workOrderSearch.d.ts diff --git a/public-typescript/workOrderSearch.js b/public/javascripts/workOrderSearch.js similarity index 100% rename from public-typescript/workOrderSearch.js rename to public/javascripts/workOrderSearch.js diff --git a/public/javascripts/workOrderSearch.min.js b/public/javascripts/workOrderSearch.min.js deleted file mode 100644 index 1e90c023..00000000 --- a/public/javascripts/workOrderSearch.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{const e=exports.los,t=exports.workOrderPrints,s=document.querySelector("#form--searchFilters");e.initializeDatePickers(s);const a=document.querySelector("#container--searchResults"),n=Number.parseInt(document.querySelector("#searchFilter--limit").value,10),r=document.querySelector("#searchFilter--offset");function o(s){var r,o,l,i,u,p,f,m,h,v,O,k,$,b,w,y,g,L,M,N;const T=s;if(0===T.workOrders.length)return void(a.innerHTML='
    \n

    There are no work orders that meet the search criteria.

    \n
    ');const S=document.createElement("tbody");for(const s of T.workOrders){let a="";for(const t of null!==(r=s.workOrderLots)&&void 0!==r?r:[])a+=`
  • \n \n \n \n ${cityssm.escapeHTML(""===(null!==(l=t.lotName)&&void 0!==l?l:"")?`(No ${e.escapedAliases.Lot} Name)`:null!==(i=t.lotName)&&void 0!==i?i:"")}\n
  • `;for(const t of null!==(u=s.workOrderLotOccupancies)&&void 0!==u?u:[])for(const s of null!==(p=t.lotOccupancyOccupants)&&void 0!==p?p:[])a+=`
  • \n \n \n \n ${cityssm.escapeHTML(""===(null!==(v=s.occupantName)&&void 0!==v?v:"")&&""===(null!==(O=s.occupantFamilyName)&&void 0!==O?O:"")?"(No Name)":`${s.occupantName} ${s.occupantFamilyName}`)}\n
  • `;S.insertAdjacentHTML("beforeend",`\n \n \n ${""===(null===(k=s.workOrderNumber)||void 0===k?void 0:k.trim())?"(No Number)":cityssm.escapeHTML(null!==($=s.workOrderNumber)&&void 0!==$?$:"")}\n \n \n ${cityssm.escapeHTML(null!==(b=s.workOrderType)&&void 0!==b?b:"")}
    \n \n ${cityssm.escapeHTML(null!==(w=s.workOrderDescription)&&void 0!==w?w:"")}\n \n \n ${""===a?"":`
      ${a}
    `}\n \n
      \n
    • \n \n \n \n ${s.workOrderOpenDateString}\n
    • \n
    • \n \n \n \n ${s.workOrderCloseDate?s.workOrderCloseDateString:`(No ${e.escapedAliases.WorkOrderCloseDate})`}\n
    • \n
    \n \n ${0===s.workOrderMilestoneCount?"-":`${(null!==(y=s.workOrderMilestoneCompletionCount)&&void 0!==y?y:"").toString()}\n /\n ${(null!==(g=s.workOrderMilestoneCount)&&void 0!==g?g:"").toString()}`}\n \n ${t.length>0?`\n \n \n \n `:""}`)}a.innerHTML=`\n \n \n \n \n \n \n ${t.length>0?'':""}\n \n
    Work Order NumberDescriptionRelatedDateProgress
    `,a.insertAdjacentHTML("beforeend",e.getSearchResultsPagerHTML(n,T.offset,T.count)),null===(L=a.querySelector("table"))||void 0===L||L.append(S),null===(M=a.querySelector("button[data-page='previous']"))||void 0===M||M.addEventListener("click",c),null===(N=a.querySelector("button[data-page='next']"))||void 0===N||N.addEventListener("click",d)}function l(){a.innerHTML=e.getLoadingParagraphHTML("Loading Work Orders..."),cityssm.postJSON(`${e.urlPrefix}/workOrders/doSearchWorkOrders`,s,o)}function i(){r.value="0",l()}function c(){r.value=Math.max(Number.parseInt(r.value,10)-n,0).toString(),l()}function d(){r.value=(Number.parseInt(r.value,10)+n).toString(),l()}const u=s.querySelectorAll("input, select");for(const e of u)e.addEventListener("change",i);s.addEventListener("submit",e=>{e.preventDefault()}),l()})(); \ No newline at end of file diff --git a/public-typescript/workOrderSearch.ts b/public/javascripts/workOrderSearch.ts similarity index 98% rename from public-typescript/workOrderSearch.ts rename to public/javascripts/workOrderSearch.ts index 0ef0b7e5..5ce925b2 100644 --- a/public-typescript/workOrderSearch.ts +++ b/public/javascripts/workOrderSearch.ts @@ -3,8 +3,8 @@ import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' -import type { LOS } from '../types/globalTypes.js' -import type { WorkOrder } from '../types/recordTypes.js' +import type { LOS } from '../../types/globalTypes.js' +import type { WorkOrder } from '../../types/recordTypes.js' declare const cityssm: cityssmGlobal diff --git a/public-typescript/workOrderView.d.ts b/public/javascripts/workOrderView.d.ts similarity index 100% rename from public-typescript/workOrderView.d.ts rename to public/javascripts/workOrderView.d.ts diff --git a/public-typescript/workOrderView.js b/public/javascripts/workOrderView.js similarity index 100% rename from public-typescript/workOrderView.js rename to public/javascripts/workOrderView.js diff --git a/public/javascripts/workOrderView.min.js b/public/javascripts/workOrderView.min.js deleted file mode 100644 index 39a3b2b3..00000000 --- a/public/javascripts/workOrderView.min.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),(()=>{var e;const r=exports.los,o=document.querySelector("#button--reopenWorkOrder");if(null!==o){const t=null!==(e=o.dataset.workOrderId)&&void 0!==e?e:"";o.addEventListener("click",()=>{bulmaJS.confirm({title:"Reopen Work Order",message:"Are you sure you want to remove the close date from this work order and reopen it?",contextualColorName:"warning",okButton:{text:"Yes, Reopen Work Order",callbackFunction:function(){cityssm.postJSON(`${r.urlPrefix}/workOrders/doReopenWorkOrder`,{workOrderId:t},e=>{var o;const n=e;n.success?window.location.href=r.getWorkOrderURL(t,!0,!0):bulmaJS.alert({title:"Error Reopening Work Order",message:null!==(o=n.errorMessage)&&void 0!==o?o:"",contextualColorName:"danger"})})}}})})}})(); \ No newline at end of file diff --git a/public-typescript/workOrderView.ts b/public/javascripts/workOrderView.ts similarity index 97% rename from public-typescript/workOrderView.ts rename to public/javascripts/workOrderView.ts index 21238b0e..b06faa57 100644 --- a/public-typescript/workOrderView.ts +++ b/public/javascripts/workOrderView.ts @@ -4,7 +4,7 @@ import type { BulmaJS } from '@cityssm/bulma-js/types.js' import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js' -import type { LOS } from '../types/globalTypes.js' +import type { LOS } from '../../types/globalTypes.js' declare const cityssm: cityssmGlobal declare const bulmaJS: BulmaJS diff --git a/tsconfig.client.json b/tsconfig.client.json index 30194fc4..16360e05 100644 --- a/tsconfig.client.json +++ b/tsconfig.client.json @@ -10,38 +10,19 @@ "skipLibCheck": true, "strictNullChecks": true }, - "files": [ - "public-typescript/adminDatabase.ts", - "public-typescript/adminFees.ts", - "public-typescript/adminLotTypes.ts", - "public-typescript/adminOccupancyTypes.ts", - "public-typescript/adminTables/adminTables.ts", - "public-typescript/adminTables/adminTablesLotOccupantTypes.ts", - "public-typescript/adminTables/adminTablesLotStatuses.ts", - "public-typescript/adminTables/adminTablesWorkOrderMilestoneTypes.ts", - "public-typescript/adminTables/adminTablesWorkOrderTypes.ts", - "public-typescript/dashboard.ts", - "public-typescript/lotEdit.ts", - "public-typescript/lotOccupancyEdit/lotOccupancyEdit.ts", - "public-typescript/lotOccupancyEdit/lotOccupancyEditComments.ts", - "public-typescript/lotOccupancyEdit/lotOccupancyEditFees.ts", - "public-typescript/lotOccupancyEdit/lotOccupancyEditOccupants.ts", - "public-typescript/lotOccupancySearch.ts", - "public-typescript/lotSearch.ts", - "public-typescript/lotView.ts", - "public-typescript/main.ts", - "public-typescript/mapEdit.ts", - "public-typescript/mapSearch.ts", - "public-typescript/mapView.ts", - "public-typescript/reportSearch.ts", - "public-typescript/workOrderEdit/workOrderEdit.ts", - "public-typescript/workOrderEdit/workOrderEditComments.ts", - "public-typescript/workOrderEdit/workOrderEditLots.ts", - "public-typescript/workOrderMilestoneCalendar.ts", - "public-typescript/workOrderOutlook.ts", - "public-typescript/workOrderSearch.ts", - "public-typescript/workOrderView.ts" - ], "compileOnSave": true, - "buildOnSave": true + "buildOnSave": true, + "include": ["public/javascripts/*"], + "exclude": [ + "bin/*", + "cypress/*", + "data/*", + "database/*", + "handlers/*", + "helpers/*", + "routes/*", + "temp/*", + "test/*", + "types/*" + ] } diff --git a/tsconfig.json b/tsconfig.json index 6e158929..8690f26b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -15,5 +15,5 @@ }, "compileOnSave": true, "buildOnSave": true, - "exclude": ["node_modules/*", "public-typescript/*"] + "exclude": ["node_modules/*", "public/javascripts/*"] } diff --git a/views/_footerA.ejs b/views/_footerA.ejs index 297ca7a2..518f37e0 100644 --- a/views/_footerA.ejs +++ b/views/_footerA.ejs @@ -40,4 +40,4 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/views/admin-database.ejs b/views/admin-database.ejs index 18fcfb40..8d99e5c2 100644 --- a/views/admin-database.ejs +++ b/views/admin-database.ejs @@ -79,6 +79,6 @@ <%- include('_footerA'); -%> - + <%- include('_footerB'); -%> diff --git a/views/admin-fees.ejs b/views/admin-fees.ejs index 3c132afc..54ba0128 100644 --- a/views/admin-fees.ejs +++ b/views/admin-fees.ejs @@ -50,6 +50,6 @@ exports.taxPercentageDefault = <%= configFunctions.getConfigProperty("settings.fees.taxPercentageDefault") %>; - + <%- include('_footerB'); -%> diff --git a/views/admin-lotTypes.ejs b/views/admin-lotTypes.ejs index 8bf47795..259f3ef0 100644 --- a/views/admin-lotTypes.ejs +++ b/views/admin-lotTypes.ejs @@ -46,6 +46,6 @@ exports.lotTypes = <%- JSON.stringify(lotTypes) %>; - + <%- include('_footerB'); -%> diff --git a/views/admin-occupancyTypes.ejs b/views/admin-occupancyTypes.ejs index cb7e2a7e..2cc89911 100644 --- a/views/admin-occupancyTypes.ejs +++ b/views/admin-occupancyTypes.ejs @@ -89,6 +89,6 @@ exports.occupancyTypePrintTitles = <%- JSON.stringify(occupancyTypePrintTitles) %>; - + <%- include('_footerB'); -%> diff --git a/views/admin-tables.ejs b/views/admin-tables.ejs index 441218e0..35882f4d 100644 --- a/views/admin-tables.ejs +++ b/views/admin-tables.ejs @@ -207,6 +207,6 @@ exports.lotOccupantTypes = <%- JSON.stringify(lotOccupantTypes) %>; - + <%- include('_footerB'); -%> diff --git a/views/dashboard.ejs b/views/dashboard.ejs index 1a136ed7..63f431a9 100644 --- a/views/dashboard.ejs +++ b/views/dashboard.ejs @@ -420,6 +420,6 @@ <%- include('_footerA'); -%> - + <%- include('_footerB'); -%> \ No newline at end of file diff --git a/views/lot-edit.ejs b/views/lot-edit.ejs index 4b57b1b4..596a2315 100644 --- a/views/lot-edit.ejs +++ b/views/lot-edit.ejs @@ -472,6 +472,6 @@ exports.lotComments = <%- JSON.stringify(lot.lotComments) %>; <% } %> - + <%- include('_footerB'); -%> diff --git a/views/lot-search.ejs b/views/lot-search.ejs index 0f1cfea7..492bcbd2 100644 --- a/views/lot-search.ejs +++ b/views/lot-search.ejs @@ -123,6 +123,6 @@ <%- include('_footerA'); -%> - + <%- include('_footerB'); -%> diff --git a/views/lot-view.ejs b/views/lot-view.ejs index 859a6862..63264c9e 100644 --- a/views/lot-view.ejs +++ b/views/lot-view.ejs @@ -216,6 +216,6 @@ <%- include('_footerA'); -%> - + <%- include('_footerB'); -%> \ No newline at end of file diff --git a/views/lotOccupancy-edit.ejs b/views/lotOccupancy-edit.ejs index c0abac3f..ac55bfd4 100644 --- a/views/lotOccupancy-edit.ejs +++ b/views/lotOccupancy-edit.ejs @@ -141,295 +141,295 @@
    -
    -
    -
    - -
    -
    -
    - -
    -
    -
    - -
    -
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    - - -
    -
    - " id="lotOccupancy--lotName" type="button" value="<%= lotOccupancy.lotName || "(No " + configFunctions.getConfigProperty("aliases.lot") + ")" %>" - <%= (configFunctions.getConfigProperty("settings.lotOccupancy.lotIdIsRequired") ? " required" : "") %> - <%= (isCreate ? "" : " disabled readonly") %> /> -
    -
    - Field"> - - -
    -
    - Field"> - - -
    -
    - -
    -
    -
    -
    -
    - -
    - - - - -
    -
    -
    - -
    - /> - - - -
    -
    -
    -
    -
    - <% if (isCreate) { %> -
    -

    - Select the <%= configFunctions.getConfigProperty("aliases.occupancy").toLowerCase() %> type to load the available fields. -

    -
    - <% } else if (lotOccupancy.lotOccupancyFields.length === 0) { %> -
    -

    - The current <%= configFunctions.getConfigProperty("aliases.occupancy").toLowerCase() %> type has no additional fields. -

    -
    - <% } else { %> - <% let occupancyTypeFieldIds = ""; %> - <% for (const lotOccupancyField of lotOccupancy.lotOccupancyFields) { %> - <% occupancyTypeFieldIds += "," + lotOccupancyField.occupancyTypeFieldId; %> -
    - -
    - <% if (!lotOccupancyField.occupancyTypeFieldValues || lotOccupancyField.occupancyTypeFieldValues === "") { %> - - pattern="<%= lotOccupancyField.pattern %>" - <% } %> - minlength="<%= lotOccupancyField.minimumLength %>" - maxlength="<%= lotOccupancyField.maximumLength %>" - <%= lotOccupancyField.isRequired ? " required" : "" %> /> - <% } else { %> - <% - const fieldValues = lotOccupancyField.occupancyTypeFieldValues.split("\n"); - let valueFound = false; - %> -
    - -
    - <% } %> -
    -
    - <% } %> - - <% } %> -
    -
    + + +
    +
    + " id="lotOccupancy--lotName" type="button" value="<%= lotOccupancy.lotName || "(No " + configFunctions.getConfigProperty("aliases.lot") + ")" %>" + <%= (configFunctions.getConfigProperty("settings.lotOccupancy.lotIdIsRequired") ? " required" : "") %> + <%= (isCreate ? "" : " disabled readonly") %> /> +
    +
    + Field"> + + +
    +
    + Field"> + + +
    +
    + +
    +
    -
    - <% if (isCreate) { %> -
    -

    <%= configFunctions.getConfigProperty("aliases.occupant") %>

    -
    -
    -
    - -
    -
    - -
    -
    +
    +
    + +
    + + + + +
    +
    +
    + +
    + /> + + + +
    +
    +
    +
    +
    + <% if (isCreate) { %> +
    +

    + Select the <%= configFunctions.getConfigProperty("aliases.occupancy").toLowerCase() %> type to load the available fields. +

    -
    -
    -
    - -
    - -
    -
    -
    -
    + <% } else if (lotOccupancy.lotOccupancyFields.length === 0) { %> +
    +

    + The current <%= configFunctions.getConfigProperty("aliases.occupancy").toLowerCase() %> type has no additional fields. +

    +
    + <% } else { %> + <% let occupancyTypeFieldIds = ""; %> + <% for (const lotOccupancyField of lotOccupancy.lotOccupancyFields) { %> + <% occupancyTypeFieldIds += "," + lotOccupancyField.occupancyTypeFieldId; %>
    - -
    - -
    + +
    + <% if (!lotOccupancyField.occupancyTypeFieldValues || lotOccupancyField.occupancyTypeFieldValues === "") { %> + + pattern="<%= lotOccupancyField.pattern %>" + <% } %> + minlength="<%= lotOccupancyField.minimumLength %>" + maxlength="<%= lotOccupancyField.maximumLength %>" + <%= lotOccupancyField.isRequired ? " required" : "" %> /> + <% } else { %> + <% + const fieldValues = lotOccupancyField.occupancyTypeFieldValues.split("\n"); + let valueFound = false; + %> +
    + +
    + <% } %> +
    + <% } %> + + <% } %> +
    +
    +
    +
    + <% if (isCreate) { %> +
    +

    <%= configFunctions.getConfigProperty("aliases.occupant") %>

    +
    +
    +
    + +
    +
    +
    +
    +
    +
    - -
    - -
    + +
    + +
    +
    +
    -
    - -
    + +
    + +
    -
    -
    -
    - -
    - " disabled /> -
    -
    -
    -
    -
    - -
    - " disabled /> -
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +
    + +
    + " disabled />
    -
    -
    - -
    - -
    +
    +
    +
    + +
    + " disabled />
    -
    -
    -
    - -
    - -
    +
    +
    + +
    +
    -
    -
    - -
    - -
    +
    +
    +
    +
    +
    + +
    +
    -
    - -
    - +
    +
    + +
    + +
    -
    -
    -

    Additional <%= configFunctions.getConfigProperty("aliases.occupants").toLowerCase() %> can be added after the record has been created.

    +
    + +
    +
    -
    - <% } %> +
    +
    +

    Additional <%= configFunctions.getConfigProperty("aliases.occupants").toLowerCase() %> can be added after the record has been created.

    +
    +
    +
    +
    + <% } %>
    @@ -465,21 +465,21 @@
    -
    -
    -
    -

    Comments

    -
    -
    -
    -
    - -
    -
    +
    +
    +
    +

    Comments

    +
    +
    +
    + +
    +
    +
    @@ -489,149 +489,149 @@ const workOrderCloseDateAlias = configFunctions.getConfigProperty("aliases.workOrderCloseDate"); %>
    -
    -
    +
    +
    +
    +

    Work Orders

    +
    +
    +
    + +
    +
    +
    +
    +
    + <% if (lotOccupancy.workOrders.length === 0) { %> +
    +

    + There are no work orders associated with this record. +

    +
    + <% } else { %> +
    + + + + + + + + + <% for (const workOrder of lotOccupancy.workOrders) { %> + + + + + + <% } %> + +
    Work Order NumberDescriptionDate
    + + <%= workOrder.workOrderNumber %> + + + <%= workOrder.workOrderType %>
    + <%= workOrder.workOrderDescription %> +
    + + + <%= workOrder.workOrderOpenDateString %> +
    + + + <% if (workOrder.workOrderCloseDate) { %> + <%= workOrder.workOrderCloseDateString %> + <% } else { %> + (No <%= workOrderCloseDateAlias %>) + <% } %> + +
    + <% } %> +
    + + +
    +
    +
    +
    +
    -

    Work Orders

    +
    +

    Fees

    +
    -
    +
    +
    -
    - <% if (lotOccupancy.workOrders.length === 0) { %> -
    -

    - There are no work orders associated with this record. -

    -
    - <% } else { %> - - - - - - - - - - <% for (const workOrder of lotOccupancy.workOrders) { %> - - - - - - <% } %> - -
    Work Order NumberDescriptionDate
    - - <%= workOrder.workOrderNumber %> - - - <%= workOrder.workOrderType %>
    - <%= workOrder.workOrderDescription %> -
    - - - <%= workOrder.workOrderOpenDateString %> -
    - - - <% if (workOrder.workOrderCloseDate) { %> - <%= workOrder.workOrderCloseDateString %> - <% } else { %> - (No <%= workOrderCloseDateAlias %>) - <% } %> - -
    - <% } %> -
    -
    - -
    -
    -
    -
    -
    -
    -
    -

    Fees

    -
    +
    +
    +
    +
    +
    +
    +
    +

    Transactions

    -
    -
    - -
    +
    +
    +
    +
    -
    +
    -
    -
    -
    -
    -
    -
    -

    Transactions

    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    +
    <% } %> <%- include('_footerA'); -%> - + <%- include('_footerB'); -%> diff --git a/views/lotOccupancy-search.ejs b/views/lotOccupancy-search.ejs index b6c3b028..1196d602 100644 --- a/views/lotOccupancy-search.ejs +++ b/views/lotOccupancy-search.ejs @@ -4,153 +4,153 @@

    - Find an <%= configFunctions.getConfigProperty("aliases.occupancy") %> Record + Find an <%= configFunctions.getConfigProperty("aliases.occupancy") %> Record

    <% if (user.userProperties.canUpdate) { %> - + <% } %>
    -
    - - -
    -
    -
    - -
    - - - - -
    -
    -
    -
    -
    - -
    -
    - -
    - - - -
    -
    -
    -
    -
    - -
    -
    - -
    - - - -
    -
    -
    + + + +
    +
    +
    + +
    + + + + +
    -
    -
    -
    - -
    -
    - -
    - - - -
    -
    -
    -
    -
    - -
    -
    - -
    - - - -
    -
    +
    +
    +
    + +
    +
    + +
    + + + +
    +
    +
    +
    +
    + +
    +
    + +
    + + + +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    + + + +
    - -
    -
    -
    - -
    - - - -
    -
    - -
    +
    +
    +
    + +
    +
    + +
    + + + +
    +
    +
    +
    + +
    +
    +
    +
    - + + + +
    +
    + +
    +
    +
    <%- include('_footerA'); -%> - + <%- include('_footerB'); -%> diff --git a/views/map-edit.ejs b/views/map-edit.ejs index 6e65bf3f..ef198073 100644 --- a/views/map-edit.ejs +++ b/views/map-edit.ejs @@ -322,6 +322,6 @@ <%- include('_footerA'); -%> - + <%- include('_footerB'); -%> \ No newline at end of file diff --git a/views/map-search.ejs b/views/map-search.ejs index 831181b1..a1166023 100644 --- a/views/map-search.ejs +++ b/views/map-search.ejs @@ -60,6 +60,6 @@ - + <%- include('_footerB'); -%> \ No newline at end of file diff --git a/views/map-view.ejs b/views/map-view.ejs index 6dad778b..0466cb5d 100644 --- a/views/map-view.ejs +++ b/views/map-view.ejs @@ -225,6 +225,6 @@ <%- include('_footerA'); -%> - + <%- include('_footerB'); -%> \ No newline at end of file diff --git a/views/report-search.ejs b/views/report-search.ejs index 296e2531..64df664b 100644 --- a/views/report-search.ejs +++ b/views/report-search.ejs @@ -632,6 +632,6 @@ <%- include('_footerA'); -%> - + <%- include('_footerB'); -%> \ No newline at end of file diff --git a/views/workOrder-edit.ejs b/views/workOrder-edit.ejs index 018843af..702f533a 100644 --- a/views/workOrder-edit.ejs +++ b/views/workOrder-edit.ejs @@ -348,6 +348,6 @@ exports.workOrderMilestoneTypes = <%- JSON.stringify(workOrderMilestoneTypes) %>; <% } %> - + <%- include('_footerB'); -%> \ No newline at end of file diff --git a/views/workOrder-milestoneCalendar.ejs b/views/workOrder-milestoneCalendar.ejs index 6f6321bd..0e1669c2 100644 --- a/views/workOrder-milestoneCalendar.ejs +++ b/views/workOrder-milestoneCalendar.ejs @@ -69,6 +69,6 @@ <%- include('_footerA'); -%> - + <%- include('_footerB'); -%> \ No newline at end of file diff --git a/views/workOrder-outlook.ejs b/views/workOrder-outlook.ejs index 6b91c25e..183e0fde 100644 --- a/views/workOrder-outlook.ejs +++ b/views/workOrder-outlook.ejs @@ -88,6 +88,6 @@ <%- include('_footerA'); -%> - + <%- include('_footerB'); -%> \ No newline at end of file diff --git a/views/workOrder-search.ejs b/views/workOrder-search.ejs index 933eb87b..2eab6923 100644 --- a/views/workOrder-search.ejs +++ b/views/workOrder-search.ejs @@ -123,6 +123,6 @@ - + <%- include('_footerB'); -%> \ No newline at end of file diff --git a/views/workOrder-view.ejs b/views/workOrder-view.ejs index e0da0162..863229d5 100644 --- a/views/workOrder-view.ejs +++ b/views/workOrder-view.ejs @@ -370,6 +370,6 @@ <%- include('_footerA'); -%> - + <%- include('_footerB'); -%> \ No newline at end of file