simplify client js
parent
b889f10b5c
commit
8cac53f6f5
48
gulpfile.js
48
gulpfile.js
|
|
@ -1,11 +1,8 @@
|
||||||
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
|
// 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 */
|
/* 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 gulp from 'gulp';
|
||||||
import changed from 'gulp-changed';
|
|
||||||
import include from 'gulp-include';
|
|
||||||
import minify from 'gulp-minify';
|
|
||||||
import gulpSass from 'gulp-sass';
|
import gulpSass from 'gulp-sass';
|
||||||
import dartSass from 'sass';
|
import * as dartSass from 'sass';
|
||||||
const sass = gulpSass(dartSass);
|
const sass = gulpSass(dartSass);
|
||||||
/*
|
/*
|
||||||
* Compile SASS
|
* Compile SASS
|
||||||
|
|
@ -20,60 +17,17 @@ function publicSCSSFunction() {
|
||||||
.pipe(gulp.dest(publicSCSSDestination));
|
.pipe(gulp.dest(publicSCSSDestination));
|
||||||
}
|
}
|
||||||
gulp.task('public-scss', publicSCSSFunction);
|
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
|
* Watch
|
||||||
*/
|
*/
|
||||||
function watchFunction() {
|
function watchFunction() {
|
||||||
gulp.watch('public-scss/*.scss', publicSCSSFunction);
|
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);
|
gulp.task('watch', watchFunction);
|
||||||
/*
|
/*
|
||||||
* Initialize default
|
* Initialize default
|
||||||
*/
|
*/
|
||||||
gulp.task('default', () => {
|
gulp.task('default', () => {
|
||||||
publicJavascriptsAdminTablesFunction();
|
|
||||||
publicJavascriptsLotOccupancyEditFunction();
|
|
||||||
publicJavascriptsWorkOrderEditFunction();
|
|
||||||
publicJavascriptsMinFunction();
|
|
||||||
publicSCSSFunction();
|
publicSCSSFunction();
|
||||||
watchFunction();
|
watchFunction();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
77
gulpfile.ts
77
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 */
|
/* 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 gulp from 'gulp'
|
||||||
import changed from 'gulp-changed'
|
|
||||||
import include from 'gulp-include'
|
|
||||||
import minify from 'gulp-minify'
|
|
||||||
import gulpSass from 'gulp-sass'
|
import gulpSass from 'gulp-sass'
|
||||||
import dartSass from 'sass'
|
import * as dartSass from 'sass'
|
||||||
|
|
||||||
const sass = gulpSass(dartSass)
|
const sass = gulpSass(dartSass)
|
||||||
|
|
||||||
|
|
@ -31,79 +28,12 @@ function publicSCSSFunction(): NodeJS.ReadWriteStream {
|
||||||
|
|
||||||
gulp.task('public-scss', publicSCSSFunction)
|
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
|
* Watch
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function watchFunction(): void {
|
function watchFunction(): void {
|
||||||
gulp.watch('public-scss/*.scss', publicSCSSFunction)
|
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)
|
gulp.task('watch', watchFunction)
|
||||||
|
|
@ -113,11 +43,6 @@ gulp.task('watch', watchFunction)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gulp.task('default', () => {
|
gulp.task('default', () => {
|
||||||
publicJavascriptsAdminTablesFunction()
|
|
||||||
publicJavascriptsLotOccupancyEditFunction()
|
|
||||||
publicJavascriptsWorkOrderEditFunction()
|
|
||||||
publicJavascriptsMinFunction()
|
|
||||||
|
|
||||||
publicSCSSFunction()
|
publicSCSSFunction()
|
||||||
|
|
||||||
watchFunction()
|
watchFunction()
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||||
"activedirectory2": "^2.2.0",
|
"activedirectory2": "^2.2.0",
|
||||||
"better-sqlite-pool": "^0.3.2",
|
"better-sqlite-pool": "^0.3.2",
|
||||||
"better-sqlite3": "^11.1.1",
|
"better-sqlite3": "^11.1.2",
|
||||||
"bulma-calendar": "^6.1.19",
|
"bulma-calendar": "^6.1.19",
|
||||||
"camelcase": "^8.0.0",
|
"camelcase": "^8.0.0",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
|
|
@ -53,7 +53,7 @@
|
||||||
"@cityssm/mssql-multi-pool": "^3.1.5",
|
"@cityssm/mssql-multi-pool": "^3.1.5",
|
||||||
"@cityssm/simple-fa5-checkbox": "^0.2.1",
|
"@cityssm/simple-fa5-checkbox": "^0.2.1",
|
||||||
"@types/activedirectory2": "^1.2.6",
|
"@types/activedirectory2": "^1.2.6",
|
||||||
"@types/better-sqlite3": "^7.6.10",
|
"@types/better-sqlite3": "^7.6.11",
|
||||||
"@types/compression": "^1.7.5",
|
"@types/compression": "^1.7.5",
|
||||||
"@types/cookie-parser": "^1.4.7",
|
"@types/cookie-parser": "^1.4.7",
|
||||||
"@types/csurf": "^1.11.5",
|
"@types/csurf": "^1.11.5",
|
||||||
|
|
@ -62,8 +62,6 @@
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^4.17.21",
|
||||||
"@types/express-session": "^1.18.0",
|
"@types/express-session": "^1.18.0",
|
||||||
"@types/gulp": "^4.0.17",
|
"@types/gulp": "^4.0.17",
|
||||||
"@types/gulp-changed": "^0.0.39",
|
|
||||||
"@types/gulp-minify": "^3.1.5",
|
|
||||||
"@types/gulp-sass": "^5.0.4",
|
"@types/gulp-sass": "^5.0.4",
|
||||||
"@types/http-errors": "^2.0.4",
|
"@types/http-errors": "^2.0.4",
|
||||||
"@types/leaflet": "^1.9.12",
|
"@types/leaflet": "^1.9.12",
|
||||||
|
|
@ -81,12 +79,9 @@
|
||||||
"bulma-steps": "^2.2.1",
|
"bulma-steps": "^2.2.1",
|
||||||
"bulma-switch": "^2.0.4",
|
"bulma-switch": "^2.0.4",
|
||||||
"bulma-tooltip": "^3.0.2",
|
"bulma-tooltip": "^3.0.2",
|
||||||
"cypress": "^13.12.0",
|
"cypress": "^13.13.0",
|
||||||
"cypress-axe": "^1.5.0",
|
"cypress-axe": "^1.5.0",
|
||||||
"gulp": "^5.0.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",
|
"gulp-sass": "^5.1.0",
|
||||||
"nodemon": "^3.1.4",
|
"nodemon": "^3.1.4",
|
||||||
"prettier-config-cityssm": "^1.0.0",
|
"prettier-config-cityssm": "^1.0.0",
|
||||||
|
|
@ -1040,9 +1035,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/better-sqlite3": {
|
"node_modules/@types/better-sqlite3": {
|
||||||
"version": "7.6.10",
|
"version": "7.6.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/better-sqlite3/-/better-sqlite3-7.6.11.tgz",
|
||||||
"integrity": "sha512-TZBjD+yOsyrUJGmcUj6OS3JADk3+UZcNv3NOBqGkM09bZdi28fNZw8ODqbMOLfKCu7RYCO62/ldq1iHbzxqoPw==",
|
"integrity": "sha512-i8KcD3PgGtGBLl3+mMYA8PdKkButvPyARxA7IQAd6qeslht13qxb1zzO8dRCtE7U3IoJS782zDBAeoKiM695kg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
|
|
@ -1210,25 +1205,6 @@
|
||||||
"chokidar": "^3.3.1"
|
"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": {
|
"node_modules/@types/gulp-sass": {
|
||||||
"version": "5.0.4",
|
"version": "5.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/gulp-sass/-/gulp-sass-5.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/gulp-sass/-/gulp-sass-5.0.4.tgz",
|
||||||
|
|
@ -1813,18 +1789,6 @@
|
||||||
"node": ">=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": {
|
"node_modules/ansi-escapes": {
|
||||||
"version": "4.3.2",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
|
||||||
|
|
@ -1852,18 +1816,6 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"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": {
|
"node_modules/ansi-regex": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
|
|
@ -1965,15 +1917,6 @@
|
||||||
"node": ">=0.10.0"
|
"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": {
|
"node_modules/arr-union": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
|
||||||
|
|
@ -2416,9 +2359,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/better-sqlite3": {
|
"node_modules/better-sqlite3": {
|
||||||
"version": "11.1.1",
|
"version": "11.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.1.2.tgz",
|
||||||
"integrity": "sha512-bAlQQb7gwCgxNpDYafK0O4AaIOiTwA7srfqRtBbw0Nsiq6P+qxEYGl3hLw+9C5jX2FVjKW7oxkSouxlJ+3VX8A==",
|
"integrity": "sha512-gujtFwavWU4MSPT+h9B+4pkvZdyOUkH54zgLdIrMmmmd4ZqiBIrRNBzNzYVFO417xo882uP5HBu4GjOfaSrIQw==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bindings": "^1.5.0",
|
"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",
|
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||||
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
|
"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": {
|
"node_modules/builtin-modules": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
|
||||||
|
|
@ -2855,18 +2792,6 @@
|
||||||
"node": ">=8"
|
"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": {
|
"node_modules/check-more-types": {
|
||||||
"version": "2.24.0",
|
"version": "2.24.0",
|
||||||
"resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz",
|
"resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz",
|
||||||
|
|
@ -3039,15 +2964,6 @@
|
||||||
"node": ">=0.8"
|
"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": {
|
"node_modules/clone-response": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
|
||||||
|
|
@ -3065,17 +2981,6 @@
|
||||||
"integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==",
|
"integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==",
|
||||||
"dev": true
|
"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": {
|
"node_modules/code-point-at": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||||
|
|
@ -3443,9 +3348,9 @@
|
||||||
"integrity": "sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg=="
|
"integrity": "sha512-p6JFxJc3M4OTD2li2qaHkDCw9SfMw82Ldr6OC9Je1aXiGfhx2W8p3GaoeaGrPJTUN9NirTM/KTxHWMUdR1rsUg=="
|
||||||
},
|
},
|
||||||
"node_modules/cypress": {
|
"node_modules/cypress": {
|
||||||
"version": "13.12.0",
|
"version": "13.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-13.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/cypress/-/cypress-13.13.0.tgz",
|
||||||
"integrity": "sha512-udzS2JilmI9ApO/UuqurEwOvThclin5ntz7K0BtnHBs+tg2Bl9QShLISXpSEMDv/u8b6mqdoAdyKeZiSqKWL8g==",
|
"integrity": "sha512-ou/MQUDq4tcDJI2FsPaod2FZpex4kpIK43JJlcBgWrX8WX7R/05ZxGTuxedOuZBfxjZxja+fbijZGyxiLP6CFA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
@ -3488,7 +3393,7 @@
|
||||||
"request-progress": "^3.0.0",
|
"request-progress": "^3.0.0",
|
||||||
"semver": "^7.5.3",
|
"semver": "^7.5.3",
|
||||||
"supports-color": "^8.1.1",
|
"supports-color": "^8.1.1",
|
||||||
"tmp": "~0.2.1",
|
"tmp": "~0.2.3",
|
||||||
"untildify": "^4.0.0",
|
"untildify": "^4.0.0",
|
||||||
"yauzl": "^2.10.0"
|
"yauzl": "^2.10.0"
|
||||||
},
|
},
|
||||||
|
|
@ -3787,12 +3692,6 @@
|
||||||
"node": ">=6.0.0"
|
"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": {
|
"node_modules/each-props": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz",
|
||||||
|
|
@ -3806,18 +3705,6 @@
|
||||||
"node": ">= 10.13.0"
|
"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": {
|
"node_modules/ecc-jsbn": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||||
|
|
@ -4749,21 +4636,6 @@
|
||||||
"node": ">= 0.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": {
|
"node_modules/event-target-shim": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||||
|
|
@ -5401,12 +5273,6 @@
|
||||||
"node": ">= 0.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": {
|
"node_modules/fs-constants": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||||
|
|
@ -5963,31 +5829,6 @@
|
||||||
"node": ">=10.13.0"
|
"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": {
|
"node_modules/gulp-cli": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz",
|
||||||
|
|
@ -6014,164 +5855,6 @@
|
||||||
"node": ">=10.13.0"
|
"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": {
|
"node_modules/gulp-sass": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-5.1.0.tgz",
|
||||||
|
|
@ -7014,12 +6697,6 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"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": {
|
"node_modules/is-valid-glob": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
|
||||||
|
|
@ -7629,12 +7306,6 @@
|
||||||
"node": ">=0.10.0"
|
"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": {
|
"node_modules/media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
|
|
@ -8539,15 +8210,6 @@
|
||||||
"node": ">=8"
|
"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": {
|
"node_modules/pe-coff": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pe-coff/-/pe-coff-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/pe-coff/-/pe-coff-1.0.0.tgz",
|
||||||
|
|
@ -9370,15 +9032,6 @@
|
||||||
"integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
|
"integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
|
||||||
"dev": true
|
"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": {
|
"node_modules/replace-homedir": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz",
|
||||||
|
|
@ -9998,15 +9651,6 @@
|
||||||
"node": ">= 14"
|
"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": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||||
|
|
@ -10016,25 +9660,6 @@
|
||||||
"node": ">=0.10.0"
|
"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": {
|
"node_modules/sparkles": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz",
|
||||||
"integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ=="
|
"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": {
|
"node_modules/sprintf-js": {
|
||||||
"version": "1.1.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
|
||||||
|
|
@ -10148,16 +9761,6 @@
|
||||||
"node": ">= 0.10.0"
|
"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": {
|
"node_modules/stream-composer": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz",
|
||||||
|
|
@ -10264,18 +9867,6 @@
|
||||||
"node": ">=8"
|
"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": {
|
"node_modules/strip-final-newline": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
|
||||||
|
|
@ -10523,38 +10114,6 @@
|
||||||
"streamx": "^2.12.5"
|
"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": {
|
"node_modules/text-decoder": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.1.0.tgz",
|
||||||
|
|
@ -10580,15 +10139,12 @@
|
||||||
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
|
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
|
||||||
},
|
},
|
||||||
"node_modules/tmp": {
|
"node_modules/tmp": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
|
||||||
"integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
|
"integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
|
||||||
"rimraf": "^3.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8.17.0"
|
"node": ">=14.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/to-regex-range": {
|
"node_modules/to-regex-range": {
|
||||||
|
|
@ -11145,23 +10701,6 @@
|
||||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||||
"integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
|
"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": {
|
"node_modules/vinyl-contents": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz",
|
||||||
|
|
@ -11543,15 +11082,6 @@
|
||||||
"node": ">=8.0"
|
"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": {
|
"node_modules/y18n": {
|
||||||
"version": "5.0.8",
|
"version": "5.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||||
|
|
|
||||||
11
package.json
11
package.json
|
|
@ -45,7 +45,7 @@
|
||||||
"@fortawesome/fontawesome-free": "^5.15.4",
|
"@fortawesome/fontawesome-free": "^5.15.4",
|
||||||
"activedirectory2": "^2.2.0",
|
"activedirectory2": "^2.2.0",
|
||||||
"better-sqlite-pool": "^0.3.2",
|
"better-sqlite-pool": "^0.3.2",
|
||||||
"better-sqlite3": "^11.1.1",
|
"better-sqlite3": "^11.1.2",
|
||||||
"bulma-calendar": "^6.1.19",
|
"bulma-calendar": "^6.1.19",
|
||||||
"camelcase": "^8.0.0",
|
"camelcase": "^8.0.0",
|
||||||
"compression": "^1.7.4",
|
"compression": "^1.7.4",
|
||||||
|
|
@ -77,7 +77,7 @@
|
||||||
"@cityssm/mssql-multi-pool": "^3.1.5",
|
"@cityssm/mssql-multi-pool": "^3.1.5",
|
||||||
"@cityssm/simple-fa5-checkbox": "^0.2.1",
|
"@cityssm/simple-fa5-checkbox": "^0.2.1",
|
||||||
"@types/activedirectory2": "^1.2.6",
|
"@types/activedirectory2": "^1.2.6",
|
||||||
"@types/better-sqlite3": "^7.6.10",
|
"@types/better-sqlite3": "^7.6.11",
|
||||||
"@types/compression": "^1.7.5",
|
"@types/compression": "^1.7.5",
|
||||||
"@types/cookie-parser": "^1.4.7",
|
"@types/cookie-parser": "^1.4.7",
|
||||||
"@types/csurf": "^1.11.5",
|
"@types/csurf": "^1.11.5",
|
||||||
|
|
@ -86,8 +86,6 @@
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^4.17.21",
|
||||||
"@types/express-session": "^1.18.0",
|
"@types/express-session": "^1.18.0",
|
||||||
"@types/gulp": "^4.0.17",
|
"@types/gulp": "^4.0.17",
|
||||||
"@types/gulp-changed": "^0.0.39",
|
|
||||||
"@types/gulp-minify": "^3.1.5",
|
|
||||||
"@types/gulp-sass": "^5.0.4",
|
"@types/gulp-sass": "^5.0.4",
|
||||||
"@types/http-errors": "^2.0.4",
|
"@types/http-errors": "^2.0.4",
|
||||||
"@types/leaflet": "^1.9.12",
|
"@types/leaflet": "^1.9.12",
|
||||||
|
|
@ -105,12 +103,9 @@
|
||||||
"bulma-steps": "^2.2.1",
|
"bulma-steps": "^2.2.1",
|
||||||
"bulma-switch": "^2.0.4",
|
"bulma-switch": "^2.0.4",
|
||||||
"bulma-tooltip": "^3.0.2",
|
"bulma-tooltip": "^3.0.2",
|
||||||
"cypress": "^13.12.0",
|
"cypress": "^13.13.0",
|
||||||
"cypress-axe": "^1.5.0",
|
"cypress-axe": "^1.5.0",
|
||||||
"gulp": "^5.0.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",
|
"gulp-sass": "^5.1.0",
|
||||||
"nodemon": "^3.1.4",
|
"nodemon": "^3.1.4",
|
||||||
"prettier-config-cityssm": "^1.0.0",
|
"prettier-config-cityssm": "^1.0.0",
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
|
||||||
`<i class="fas fa-fw fa-${fontAwesomeIconClass}" aria-hidden="true"></i>`;
|
|
||||||
}
|
|
||||||
"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?<br />
|
|
||||||
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 = `<tr><td colspan="2">
|
|
||||||
<div class="message is-warning"><p class="message-body">There are no active work order types.</p></div>
|
|
||||||
</td></tr>`;
|
|
||||||
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 = `<td>
|
|
||||||
<form>
|
|
||||||
<input name="workOrderTypeId" type="hidden" value="${workOrderType.workOrderTypeId.toString()}" />
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="workOrderType" type="text"
|
|
||||||
value="${cityssm.escapeHTML(workOrderType.workOrderType ?? '')}" maxlength="100" aria-label="Work Order Type" required />
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-success" type="submit" aria-label="Save">
|
|
||||||
<i class="fas fa-save" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<div class="field is-grouped">
|
|
||||||
<div class="control">
|
|
||||||
${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderTypeUp', 'button--moveWorkOrderTypeDown', false)}
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-danger is-light button--deleteWorkOrderType" data-tooltip="Delete Work Order Type" type="button" aria-label="Delete Work Order Type">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>`;
|
|
||||||
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?<br />
|
|
||||||
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 = `<tr><td colspan="2">
|
|
||||||
<div class="message is-warning"><p class="message-body">There are no active work order milestone types.</p></div>
|
|
||||||
</td></tr>`;
|
|
||||||
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 = `<td>
|
|
||||||
<form>
|
|
||||||
<input name="workOrderMilestoneTypeId" type="hidden" value="${workOrderMilestoneType.workOrderMilestoneTypeId.toString()}" />
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="workOrderMilestoneType" type="text"
|
|
||||||
value="${cityssm.escapeHTML(workOrderMilestoneType.workOrderMilestoneType)}" maxlength="100" aria-label="Work Order Milestone Type" required />
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-success" type="submit" aria-label="Save">
|
|
||||||
<i class="fas fa-save" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<div class="field is-grouped">
|
|
||||||
<div class="control">
|
|
||||||
${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderMilestoneTypeUp', 'button--moveWorkOrderMilestoneTypeDown', false)}
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-danger is-light button--deleteWorkOrderMilestoneType" data-tooltip="Delete Mielstone Type" type="button" aria-label="Delete Milestone Type">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>`;
|
|
||||||
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?<br />
|
|
||||||
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 = `<tr><td colspan="2">
|
|
||||||
<div class="message is-warning"><p class="message-body">There are no active ${los.escapedAliases.lot} statuses.</p></div>
|
|
||||||
</td></tr>`;
|
|
||||||
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 = `<td>
|
|
||||||
<form>
|
|
||||||
<input name="lotStatusId" type="hidden" value="${lotStatus.lotStatusId.toString()}" />
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="lotStatus" type="text"
|
|
||||||
value="${cityssm.escapeHTML(lotStatus.lotStatus)}"
|
|
||||||
aria-label="${los.escapedAliases.Lot} Status" maxlength="100" required />
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-success" type="submit" aria-label="Save">
|
|
||||||
<i class="fas fa-save" aria-hidden="true"></i>\
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<div class="field is-grouped">
|
|
||||||
<div class="control">
|
|
||||||
${los.getMoveUpDownButtonFieldHTML('button--moveLotStatusUp', 'button--moveLotStatusDown', false)}
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-danger is-light button--deleteLotStatus" data-tooltip="Delete Status" type="button" aria-label="Delete Status">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>`;
|
|
||||||
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?<br />
|
|
||||||
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 = `<tr><td colspan="3">
|
|
||||||
<div class="message is-warning">
|
|
||||||
<p class="message-body">There are no active ${los.escapedAliases.lot} ${los.escapedAliases.occupant} types.</p>
|
|
||||||
</div>
|
|
||||||
</td></tr>`;
|
|
||||||
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 = `<td>
|
|
||||||
<div class="field">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="lotOccupantType" type="text"
|
|
||||||
value="${cityssm.escapeHTML(lotOccupantType.lotOccupantType)}"
|
|
||||||
form="${formId}"
|
|
||||||
aria-label="${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type" maxlength="100" required />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td><td>
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="control">
|
|
||||||
<span class="button is-static">fa-</span>
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="fontAwesomeIconClass" type="text"
|
|
||||||
value="${cityssm.escapeHTML(lotOccupantType.fontAwesomeIconClass)}"
|
|
||||||
form="${formId}"
|
|
||||||
list="datalist--fontAwesomeIconClass" aria-label="Icon Name" maxlength="50" />
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<span class="button is-static">
|
|
||||||
<i class="fas fa-fw fa-${cityssm.escapeHTML(lotOccupantType.fontAwesomeIconClass)}"></i>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td><td>
|
|
||||||
<div class="field">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="occupantCommentTitle" type="text"
|
|
||||||
value="${cityssm.escapeHTML(lotOccupantType.occupantCommentTitle)}"
|
|
||||||
form="${formId}"
|
|
||||||
aria-label="${los.escapedAliases.Occupant} Comment Title" maxlength="50" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td><td>
|
|
||||||
<form id="${formId}">
|
|
||||||
<input name="lotOccupantTypeId" type="hidden"
|
|
||||||
value="${lotOccupantType.lotOccupantTypeId.toString()}" />
|
|
||||||
<button class="button is-success" type="submit" aria-label="Save">
|
|
||||||
<i class="fas fa-save" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<div class="field is-grouped">
|
|
||||||
<div class="control">
|
|
||||||
${los.getMoveUpDownButtonFieldHTML('button--moveLotOccupantTypeUp', 'button--moveLotOccupantTypeDown', false)}
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-danger is-light button--deleteLotOccupantType"
|
|
||||||
data-tooltip="Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type"
|
|
||||||
type="button"
|
|
||||||
aria-label="Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>`;
|
|
||||||
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();
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
@ -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 =
|
|
||||||
`<i class="fas fa-fw fa-${fontAwesomeIconClass}" aria-hidden="true"></i>`;
|
|
||||||
}
|
|
||||||
//=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
|
|
||||||
})();
|
|
||||||
|
|
@ -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<string, unknown>
|
|
||||||
;(() => {
|
|
||||||
// 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<HTMLButtonElement>
|
|
||||||
)[1].innerHTML =
|
|
||||||
`<i class="fas fa-fw fa-${fontAwesomeIconClass}" aria-hidden="true"></i>`
|
|
||||||
}
|
|
||||||
|
|
||||||
//=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
|
|
||||||
})()
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export {};
|
|
||||||
|
|
@ -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?<br />
|
|
||||||
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 = `<tr><td colspan="3">
|
|
||||||
<div class="message is-warning">
|
|
||||||
<p class="message-body">There are no active ${los.escapedAliases.lot} ${los.escapedAliases.occupant} types.</p>
|
|
||||||
</div>
|
|
||||||
</td></tr>`;
|
|
||||||
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 = `<td>
|
|
||||||
<div class="field">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="lotOccupantType" type="text"
|
|
||||||
value="${cityssm.escapeHTML(lotOccupantType.lotOccupantType)}"
|
|
||||||
form="${formId}"
|
|
||||||
aria-label="${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type" maxlength="100" required />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td><td>
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="control">
|
|
||||||
<span class="button is-static">fa-</span>
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="fontAwesomeIconClass" type="text"
|
|
||||||
value="${cityssm.escapeHTML(lotOccupantType.fontAwesomeIconClass)}"
|
|
||||||
form="${formId}"
|
|
||||||
list="datalist--fontAwesomeIconClass" aria-label="Icon Name" maxlength="50" />
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<span class="button is-static">
|
|
||||||
<i class="fas fa-fw fa-${cityssm.escapeHTML(lotOccupantType.fontAwesomeIconClass)}"></i>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td><td>
|
|
||||||
<div class="field">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="occupantCommentTitle" type="text"
|
|
||||||
value="${cityssm.escapeHTML(lotOccupantType.occupantCommentTitle)}"
|
|
||||||
form="${formId}"
|
|
||||||
aria-label="${los.escapedAliases.Occupant} Comment Title" maxlength="50" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td><td>
|
|
||||||
<form id="${formId}">
|
|
||||||
<input name="lotOccupantTypeId" type="hidden"
|
|
||||||
value="${lotOccupantType.lotOccupantTypeId.toString()}" />
|
|
||||||
<button class="button is-success" type="submit" aria-label="Save">
|
|
||||||
<i class="fas fa-save" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<div class="field is-grouped">
|
|
||||||
<div class="control">
|
|
||||||
${los.getMoveUpDownButtonFieldHTML('button--moveLotOccupantTypeUp', 'button--moveLotOccupantTypeDown', false)}
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-danger is-light button--deleteLotOccupantType"
|
|
||||||
data-tooltip="Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type"
|
|
||||||
type="button"
|
|
||||||
aria-label="Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>`;
|
|
||||||
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();
|
|
||||||
|
|
@ -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<string, unknown>
|
|
||||||
|
|
||||||
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?<br />
|
|
||||||
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 = `<tr><td colspan="3">
|
|
||||||
<div class="message is-warning">
|
|
||||||
<p class="message-body">There are no active ${los.escapedAliases.lot} ${los.escapedAliases.occupant} types.</p>
|
|
||||||
</div>
|
|
||||||
</td></tr>`
|
|
||||||
|
|
||||||
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 = `<td>
|
|
||||||
<div class="field">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="lotOccupantType" type="text"
|
|
||||||
value="${cityssm.escapeHTML(lotOccupantType.lotOccupantType)}"
|
|
||||||
form="${formId}"
|
|
||||||
aria-label="${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type" maxlength="100" required />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td><td>
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="control">
|
|
||||||
<span class="button is-static">fa-</span>
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="fontAwesomeIconClass" type="text"
|
|
||||||
value="${cityssm.escapeHTML(lotOccupantType.fontAwesomeIconClass)}"
|
|
||||||
form="${formId}"
|
|
||||||
list="datalist--fontAwesomeIconClass" aria-label="Icon Name" maxlength="50" />
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<span class="button is-static">
|
|
||||||
<i class="fas fa-fw fa-${cityssm.escapeHTML(lotOccupantType.fontAwesomeIconClass)}"></i>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td><td>
|
|
||||||
<div class="field">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="occupantCommentTitle" type="text"
|
|
||||||
value="${cityssm.escapeHTML(lotOccupantType.occupantCommentTitle)}"
|
|
||||||
form="${formId}"
|
|
||||||
aria-label="${los.escapedAliases.Occupant} Comment Title" maxlength="50" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td><td>
|
|
||||||
<form id="${formId}">
|
|
||||||
<input name="lotOccupantTypeId" type="hidden"
|
|
||||||
value="${lotOccupantType.lotOccupantTypeId.toString()}" />
|
|
||||||
<button class="button is-success" type="submit" aria-label="Save">
|
|
||||||
<i class="fas fa-save" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<div class="field is-grouped">
|
|
||||||
<div class="control">
|
|
||||||
${los.getMoveUpDownButtonFieldHTML(
|
|
||||||
'button--moveLotOccupantTypeUp',
|
|
||||||
'button--moveLotOccupantTypeDown',
|
|
||||||
false
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-danger is-light button--deleteLotOccupantType"
|
|
||||||
data-tooltip="Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type"
|
|
||||||
type="button"
|
|
||||||
aria-label="Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>`
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export {};
|
|
||||||
|
|
@ -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?<br />
|
|
||||||
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 = `<tr><td colspan="2">
|
|
||||||
<div class="message is-warning"><p class="message-body">There are no active ${los.escapedAliases.lot} statuses.</p></div>
|
|
||||||
</td></tr>`;
|
|
||||||
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 = `<td>
|
|
||||||
<form>
|
|
||||||
<input name="lotStatusId" type="hidden" value="${lotStatus.lotStatusId.toString()}" />
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="lotStatus" type="text"
|
|
||||||
value="${cityssm.escapeHTML(lotStatus.lotStatus)}"
|
|
||||||
aria-label="${los.escapedAliases.Lot} Status" maxlength="100" required />
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-success" type="submit" aria-label="Save">
|
|
||||||
<i class="fas fa-save" aria-hidden="true"></i>\
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<div class="field is-grouped">
|
|
||||||
<div class="control">
|
|
||||||
${los.getMoveUpDownButtonFieldHTML('button--moveLotStatusUp', 'button--moveLotStatusDown', false)}
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-danger is-light button--deleteLotStatus" data-tooltip="Delete Status" type="button" aria-label="Delete Status">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>`;
|
|
||||||
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();
|
|
||||||
|
|
@ -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<string, unknown>
|
|
||||||
|
|
||||||
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?<br />
|
|
||||||
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 = `<tr><td colspan="2">
|
|
||||||
<div class="message is-warning"><p class="message-body">There are no active ${los.escapedAliases.lot} statuses.</p></div>
|
|
||||||
</td></tr>`
|
|
||||||
|
|
||||||
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 = `<td>
|
|
||||||
<form>
|
|
||||||
<input name="lotStatusId" type="hidden" value="${lotStatus.lotStatusId.toString()}" />
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="lotStatus" type="text"
|
|
||||||
value="${cityssm.escapeHTML(lotStatus.lotStatus)}"
|
|
||||||
aria-label="${los.escapedAliases.Lot} Status" maxlength="100" required />
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-success" type="submit" aria-label="Save">
|
|
||||||
<i class="fas fa-save" aria-hidden="true"></i>\
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<div class="field is-grouped">
|
|
||||||
<div class="control">
|
|
||||||
${los.getMoveUpDownButtonFieldHTML(
|
|
||||||
'button--moveLotStatusUp',
|
|
||||||
'button--moveLotStatusDown',
|
|
||||||
false
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-danger is-light button--deleteLotStatus" data-tooltip="Delete Status" type="button" aria-label="Delete Status">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>`
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export {};
|
|
||||||
|
|
@ -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?<br />
|
|
||||||
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 = `<tr><td colspan="2">
|
|
||||||
<div class="message is-warning"><p class="message-body">There are no active work order milestone types.</p></div>
|
|
||||||
</td></tr>`;
|
|
||||||
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 = `<td>
|
|
||||||
<form>
|
|
||||||
<input name="workOrderMilestoneTypeId" type="hidden" value="${workOrderMilestoneType.workOrderMilestoneTypeId.toString()}" />
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="workOrderMilestoneType" type="text"
|
|
||||||
value="${cityssm.escapeHTML(workOrderMilestoneType.workOrderMilestoneType)}" maxlength="100" aria-label="Work Order Milestone Type" required />
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-success" type="submit" aria-label="Save">
|
|
||||||
<i class="fas fa-save" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<div class="field is-grouped">
|
|
||||||
<div class="control">
|
|
||||||
${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderMilestoneTypeUp', 'button--moveWorkOrderMilestoneTypeDown', false)}
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-danger is-light button--deleteWorkOrderMilestoneType" data-tooltip="Delete Mielstone Type" type="button" aria-label="Delete Milestone Type">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>`;
|
|
||||||
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();
|
|
||||||
|
|
@ -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<string, unknown>
|
|
||||||
|
|
||||||
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?<br />
|
|
||||||
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 = `<tr><td colspan="2">
|
|
||||||
<div class="message is-warning"><p class="message-body">There are no active work order milestone types.</p></div>
|
|
||||||
</td></tr>`
|
|
||||||
|
|
||||||
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 = `<td>
|
|
||||||
<form>
|
|
||||||
<input name="workOrderMilestoneTypeId" type="hidden" value="${workOrderMilestoneType.workOrderMilestoneTypeId.toString()}" />
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="workOrderMilestoneType" type="text"
|
|
||||||
value="${cityssm.escapeHTML(workOrderMilestoneType.workOrderMilestoneType)}" maxlength="100" aria-label="Work Order Milestone Type" required />
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-success" type="submit" aria-label="Save">
|
|
||||||
<i class="fas fa-save" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<div class="field is-grouped">
|
|
||||||
<div class="control">
|
|
||||||
${los.getMoveUpDownButtonFieldHTML(
|
|
||||||
'button--moveWorkOrderMilestoneTypeUp',
|
|
||||||
'button--moveWorkOrderMilestoneTypeDown',
|
|
||||||
false
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-danger is-light button--deleteWorkOrderMilestoneType" data-tooltip="Delete Mielstone Type" type="button" aria-label="Delete Milestone Type">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>`
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export {};
|
|
||||||
|
|
@ -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?<br />
|
|
||||||
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 = `<tr><td colspan="2">
|
|
||||||
<div class="message is-warning"><p class="message-body">There are no active work order types.</p></div>
|
|
||||||
</td></tr>`;
|
|
||||||
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 = `<td>
|
|
||||||
<form>
|
|
||||||
<input name="workOrderTypeId" type="hidden" value="${workOrderType.workOrderTypeId.toString()}" />
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="workOrderType" type="text"
|
|
||||||
value="${cityssm.escapeHTML(workOrderType.workOrderType ?? '')}" maxlength="100" aria-label="Work Order Type" required />
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-success" type="submit" aria-label="Save">
|
|
||||||
<i class="fas fa-save" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<div class="field is-grouped">
|
|
||||||
<div class="control">
|
|
||||||
${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderTypeUp', 'button--moveWorkOrderTypeDown', false)}
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-danger is-light button--deleteWorkOrderType" data-tooltip="Delete Work Order Type" type="button" aria-label="Delete Work Order Type">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>`;
|
|
||||||
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();
|
|
||||||
|
|
@ -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<string, unknown>
|
|
||||||
|
|
||||||
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?<br />
|
|
||||||
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 = `<tr><td colspan="2">
|
|
||||||
<div class="message is-warning"><p class="message-body">There are no active work order types.</p></div>
|
|
||||||
</td></tr>`
|
|
||||||
|
|
||||||
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 = `<td>
|
|
||||||
<form>
|
|
||||||
<input name="workOrderTypeId" type="hidden" value="${workOrderType.workOrderTypeId.toString()}" />
|
|
||||||
<div class="field has-addons">
|
|
||||||
<div class="control">
|
|
||||||
<input class="input" name="workOrderType" type="text"
|
|
||||||
value="${cityssm.escapeHTML(workOrderType.workOrderType ?? '')}" maxlength="100" aria-label="Work Order Type" required />
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-success" type="submit" aria-label="Save">
|
|
||||||
<i class="fas fa-save" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<div class="field is-grouped">
|
|
||||||
<div class="control">
|
|
||||||
${los.getMoveUpDownButtonFieldHTML(
|
|
||||||
'button--moveWorkOrderTypeUp',
|
|
||||||
'button--moveWorkOrderTypeDown',
|
|
||||||
false
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div class="control">
|
|
||||||
<button class="button is-danger is-light button--deleteWorkOrderType" data-tooltip="Delete Work Order Type" type="button" aria-label="Delete Work Order Type">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</td>`
|
|
||||||
|
|
||||||
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()
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">Select the ${los.escapedAliases.occupancy} type to load the available fields.</p>
|
|
||||||
</div>`;
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no additional fields for this ${los.escapedAliases.occupancy} type.</p>
|
|
||||||
</div>`;
|
|
||||||
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 = `<label class="label" for="${cityssm.escapeHTML(fieldId)}"></label><div class="control"></div>`;
|
|
||||||
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 = `<div class="select is-fullwidth">
|
|
||||||
<select id="${cityssm.escapeHTML(fieldId)}" name="${cityssm.escapeHTML(fieldName)}">
|
|
||||||
<option value="">(Not Set)</option>
|
|
||||||
</select>
|
|
||||||
</div>`;
|
|
||||||
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
|
|
||||||
`<input name="occupancyTypeFieldIds" type="hidden"
|
|
||||||
value="${cityssm.escapeHTML(occupancyTypeFieldIds.slice(1))}" />`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">No results.</p>
|
|
||||||
</div>`;
|
|
||||||
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 = `<div class="columns">
|
|
||||||
<div class="column">
|
|
||||||
${cityssm.escapeHTML(lot.lotName ?? '')}<br />
|
|
||||||
<span class="is-size-7">${cityssm.escapeHTML(lot.mapName ?? '')}</span>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
${cityssm.escapeHTML(lot.lotStatus)}<br />
|
|
||||||
<span class="is-size-7">
|
|
||||||
${lot.lotOccupancyCount > 0 ? 'Currently Occupied' : ''}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
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
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
@ -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<string, unknown>
|
|
||||||
;(() => {
|
|
||||||
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<string, unknown>)
|
|
||||||
.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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">Select the ${los.escapedAliases.occupancy} type to load the available fields.</p>
|
|
||||||
</div>`
|
|
||||||
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no additional fields for this ${los.escapedAliases.occupancy} type.</p>
|
|
||||||
</div>`
|
|
||||||
|
|
||||||
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 = `<label class="label" for="${cityssm.escapeHTML(fieldId)}"></label><div class="control"></div>`
|
|
||||||
;(
|
|
||||||
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 = `<div class="select is-fullwidth">
|
|
||||||
<select id="${cityssm.escapeHTML(fieldId)}" name="${cityssm.escapeHTML(fieldName)}">
|
|
||||||
<option value="">(Not Set)</option>
|
|
||||||
</select>
|
|
||||||
</div>`
|
|
||||||
|
|
||||||
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
|
|
||||||
`<input name="occupancyTypeFieldIds" type="hidden"
|
|
||||||
value="${cityssm.escapeHTML(occupancyTypeFieldIds.slice(1))}" />`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
} 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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">No results.</p>
|
|
||||||
</div>`
|
|
||||||
|
|
||||||
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 = `<div class="columns">
|
|
||||||
<div class="column">
|
|
||||||
${cityssm.escapeHTML(lot.lotName ?? '')}<br />
|
|
||||||
<span class="is-size-7">${cityssm.escapeHTML(lot.mapName ?? '')}</span>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
${cityssm.escapeHTML(lot.lotStatus as string)}<br />
|
|
||||||
<span class="is-size-7">
|
|
||||||
${lot.lotOccupancyCount! > 0 ? 'Currently Occupied' : ''}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>`
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export {};
|
|
||||||
|
|
@ -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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no comments associated with this record.</p>
|
|
||||||
</div>`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const tableElement = document.createElement('table');
|
|
||||||
tableElement.className = 'table is-fullwidth is-striped is-hoverable';
|
|
||||||
tableElement.innerHTML = `<thead><tr>
|
|
||||||
<th>Commentor</th>
|
|
||||||
<th>Comment Date</th>
|
|
||||||
<th>Comment</th>
|
|
||||||
<th class="is-hidden-print"><span class="is-sr-only">Options</span></th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>`;
|
|
||||||
for (const lotOccupancyComment of lotOccupancyComments) {
|
|
||||||
const tableRowElement = document.createElement('tr');
|
|
||||||
tableRowElement.dataset.lotOccupancyCommentId =
|
|
||||||
lotOccupancyComment.lotOccupancyCommentId?.toString();
|
|
||||||
tableRowElement.innerHTML = `<td>${cityssm.escapeHTML(lotOccupancyComment.recordCreate_userName ?? '')}</td>
|
|
||||||
<td>
|
|
||||||
${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyCommentDateString ?? '')}
|
|
||||||
${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyCommentTime === 0
|
|
||||||
? ''
|
|
||||||
: lotOccupancyComment.lotOccupancyCommentTimePeriodString ?? '')}
|
|
||||||
</td>
|
|
||||||
<td>${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyComment ?? '')}</td>
|
|
||||||
<td class="is-hidden-print">
|
|
||||||
<div class="buttons are-small is-justify-content-end">
|
|
||||||
<button class="button is-primary button--edit" type="button">
|
|
||||||
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
|
|
||||||
<span>Edit</span>
|
|
||||||
</button>
|
|
||||||
<button class="button is-light is-danger button--delete" data-tooltip="Delete Comment" type="button" aria-label="Delete">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</td>`;
|
|
||||||
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();
|
|
||||||
|
|
@ -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<string, unknown>
|
|
||||||
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no comments associated with this record.</p>
|
|
||||||
</div>`
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const tableElement = document.createElement('table')
|
|
||||||
tableElement.className = 'table is-fullwidth is-striped is-hoverable'
|
|
||||||
tableElement.innerHTML = `<thead><tr>
|
|
||||||
<th>Commentor</th>
|
|
||||||
<th>Comment Date</th>
|
|
||||||
<th>Comment</th>
|
|
||||||
<th class="is-hidden-print"><span class="is-sr-only">Options</span></th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>`
|
|
||||||
|
|
||||||
for (const lotOccupancyComment of lotOccupancyComments) {
|
|
||||||
const tableRowElement = document.createElement('tr')
|
|
||||||
tableRowElement.dataset.lotOccupancyCommentId =
|
|
||||||
lotOccupancyComment.lotOccupancyCommentId?.toString()
|
|
||||||
|
|
||||||
tableRowElement.innerHTML = `<td>${cityssm.escapeHTML(lotOccupancyComment.recordCreate_userName ?? '')}</td>
|
|
||||||
<td>
|
|
||||||
${cityssm.escapeHTML(
|
|
||||||
lotOccupancyComment.lotOccupancyCommentDateString ?? ''
|
|
||||||
)}
|
|
||||||
${cityssm.escapeHTML(
|
|
||||||
lotOccupancyComment.lotOccupancyCommentTime === 0
|
|
||||||
? ''
|
|
||||||
: lotOccupancyComment.lotOccupancyCommentTimePeriodString ?? ''
|
|
||||||
)}
|
|
||||||
</td>
|
|
||||||
<td>${cityssm.escapeHTML(lotOccupancyComment.lotOccupancyComment ?? '')}</td>
|
|
||||||
<td class="is-hidden-print">
|
|
||||||
<div class="buttons are-small is-justify-content-end">
|
|
||||||
<button class="button is-primary button--edit" type="button">
|
|
||||||
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
|
|
||||||
<span>Edit</span>
|
|
||||||
</button>
|
|
||||||
<button class="button is-light is-danger button--delete" data-tooltip="Delete Comment" type="button" aria-label="Delete">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</td>`
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export {};
|
|
||||||
|
|
@ -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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no fees associated with this record.</p>
|
|
||||||
</div>`;
|
|
||||||
renderLotOccupancyTransactions();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line no-secrets/no-secrets
|
|
||||||
lotOccupancyFeesContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable">
|
|
||||||
<thead><tr>
|
|
||||||
<th>Fee</th>
|
|
||||||
<th><span class="is-sr-only">Unit Cost</span></th>
|
|
||||||
<th class="has-width-1"><span class="is-sr-only">×</span></th>
|
|
||||||
<th class="has-width-1"><span class="is-sr-only">Quantity</span></th>
|
|
||||||
<th class="has-width-1"><span class="is-sr-only">equals</span></th>
|
|
||||||
<th class="has-width-1 has-text-right">Total</th>
|
|
||||||
<th class="has-width-1 is-hidden-print"><span class="is-sr-only">Options</span></th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
<tfoot><tr>
|
|
||||||
<th colspan="5">Subtotal</th>
|
|
||||||
<td class="has-text-weight-bold has-text-right" id="lotOccupancyFees--feeAmountTotal"></td>
|
|
||||||
<td class="is-hidden-print"></td>
|
|
||||||
</tr><tr>
|
|
||||||
<th colspan="5">Tax</th>
|
|
||||||
<td class="has-text-right" id="lotOccupancyFees--taxAmountTotal"></td>
|
|
||||||
<td class="is-hidden-print"></td>
|
|
||||||
</tr><tr>
|
|
||||||
<th colspan="5">Grand Total</th>
|
|
||||||
<td class="has-text-weight-bold has-text-right" id="lotOccupancyFees--grandTotal"></td>
|
|
||||||
<td class="is-hidden-print"></td>
|
|
||||||
</tr></tfoot></table>`;
|
|
||||||
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 = `<td colspan="${lotOccupancyFee.quantity === 1 ? '5' : '1'}">
|
|
||||||
${cityssm.escapeHTML(lotOccupancyFee.feeName ?? '')}<br />
|
|
||||||
<span class="tag">${cityssm.escapeHTML(lotOccupancyFee.feeCategory ?? '')}</span>
|
|
||||||
</td>
|
|
||||||
${lotOccupancyFee.quantity === 1
|
|
||||||
? ''
|
|
||||||
: `<td class="has-text-right">
|
|
||||||
$${lotOccupancyFee.feeAmount?.toFixed(2)}
|
|
||||||
</td>
|
|
||||||
<td>×</td>
|
|
||||||
<td class="has-text-right">${lotOccupancyFee.quantity?.toString()}</td>
|
|
||||||
<td>=</td>`}
|
|
||||||
<td class="has-text-right">
|
|
||||||
$${((lotOccupancyFee.feeAmount ?? 0) * (lotOccupancyFee.quantity ?? 0)).toFixed(2)}
|
|
||||||
</td>
|
|
||||||
<td class="is-hidden-print">
|
|
||||||
<div class="buttons are-small is-flex-wrap-nowrap is-justify-content-end">
|
|
||||||
${lotOccupancyFee.includeQuantity ?? false
|
|
||||||
? `<button class="button is-primary button--editQuantity">
|
|
||||||
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
|
|
||||||
<span>Edit</span>
|
|
||||||
</button>`
|
|
||||||
: ''}
|
|
||||||
<button class="button is-danger is-light button--delete" data-tooltip="Delete Fee" type="button">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</td>`;
|
|
||||||
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 = `<div class="columns is-vcentered">
|
|
||||||
<div class="column">
|
|
||||||
<h4 class="title is-5">
|
|
||||||
${cityssm.escapeHTML(feeCategory.feeCategory ?? '')}
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="panel mb-5"></div>`;
|
|
||||||
if (feeCategory.isGroupedFee) {
|
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
|
||||||
categoryContainerElement.querySelector('.columns')?.insertAdjacentHTML('beforeend', `<div class="column is-narrow has-text-right">
|
|
||||||
<button class="button is-small is-success" type="button" data-fee-category-id="${feeCategory.feeCategoryId}">
|
|
||||||
<span class="icon is-small"><i class="fas fa-plus" aria-hidden="true"></i></span>
|
|
||||||
<span>Add Fee Group</span>
|
|
||||||
</button>
|
|
||||||
</div>`);
|
|
||||||
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 = `<strong>${cityssm.escapeHTML(fee.feeName ?? '')}</strong><br />
|
|
||||||
<small>
|
|
||||||
${
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
||||||
cityssm
|
|
||||||
.escapeHTML(fee.feeDescription ?? '')
|
|
||||||
.replaceAll('\n', '<br />')}
|
|
||||||
</small>`;
|
|
||||||
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 = `<div class="message ${lotOccupancyFees.length === 0 ? 'is-info' : 'is-warning'}">
|
|
||||||
<p class="message-body">There are no transactions associated with this record.</p>
|
|
||||||
</div>`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
|
||||||
lotOccupancyTransactionsContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable">
|
|
||||||
<thead><tr>
|
|
||||||
<th class="has-width-1">Date</th>
|
|
||||||
<th>${los.escapedAliases.ExternalReceiptNumber}</th>
|
|
||||||
<th class="has-text-right has-width-1">Amount</th>
|
|
||||||
<th class="has-width-1 is-hidden-print"><span class="is-sr-only">Options</span></th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
<tfoot><tr>
|
|
||||||
<th colspan="2">Transaction Total</th>
|
|
||||||
<td class="has-text-weight-bold has-text-right" id="lotOccupancyTransactions--grandTotal"></td>
|
|
||||||
<td class="is-hidden-print"></td>
|
|
||||||
</tr></tfoot>
|
|
||||||
</table>`;
|
|
||||||
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 += ` <span data-tooltip="No Matching Document Found">
|
|
||||||
<i class="fas fa-times-circle has-text-danger" aria-label="No Matching Document Found"></i>
|
|
||||||
</span>`;
|
|
||||||
}
|
|
||||||
else if (lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(2) === lotOccupancyTransaction.transactionAmount.toFixed(2)) {
|
|
||||||
externalReceiptNumberHTML += ` <span data-tooltip="Matching Document Found">
|
|
||||||
<i class="fas fa-check-circle has-text-success" aria-label="Matching Document Found"></i>
|
|
||||||
</span>`;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
externalReceiptNumberHTML += ` <span data-tooltip="Matching Document: $${lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(2)}">
|
|
||||||
<i class="fas fa-check-circle has-text-warning" aria-label="Matching Document: $${lotOccupancyTransaction.dynamicsGPDocument.documentTotal.toFixed(2)}"></i>
|
|
||||||
</span>`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
externalReceiptNumberHTML += '<br />';
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
|
||||||
tableRowElement.innerHTML = `<td>
|
|
||||||
${cityssm.escapeHTML(lotOccupancyTransaction.transactionDateString ?? '')}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
${externalReceiptNumberHTML}
|
|
||||||
<small>${cityssm.escapeHTML(lotOccupancyTransaction.transactionNote ?? '')}</small>
|
|
||||||
</td>
|
|
||||||
<td class="has-text-right">
|
|
||||||
$${cityssm.escapeHTML(lotOccupancyTransaction.transactionAmount.toFixed(2))}
|
|
||||||
</td>
|
|
||||||
<td class="is-hidden-print">
|
|
||||||
<div class="buttons are-small is-flex-wrap-nowrap is-justify-content-end">
|
|
||||||
<button class="button is-primary button--edit" type="button">
|
|
||||||
<span class="icon"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
|
|
||||||
<span>Edit</span>
|
|
||||||
</button>
|
|
||||||
<button class="button is-danger is-light button--delete" data-tooltip="Delete Transaction" type="button">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</td>`;
|
|
||||||
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', `<div class="message is-warning">
|
|
||||||
<div class="message-body">
|
|
||||||
<div class="level">
|
|
||||||
<div class="level-left">
|
|
||||||
<div class="level-item">Outstanding Balance</div>
|
|
||||||
</div>
|
|
||||||
<div class="level-right">
|
|
||||||
<div class="level-item">
|
|
||||||
$${cityssm.escapeHTML((feeGrandTotal - transactionGrandTotal).toFixed(2))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div></div>`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 = '<i class="fas fa-minus" aria-hidden="true"></i>';
|
|
||||||
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 =
|
|
||||||
'<i class="fas fa-times-circle" aria-hidden="true"></i>';
|
|
||||||
}
|
|
||||||
else if (transactionAmountElement.valueAsNumber ===
|
|
||||||
responseJSON.dynamicsGPDocument.documentTotal) {
|
|
||||||
helpTextElement.textContent = 'Matching Document Found';
|
|
||||||
iconElement.innerHTML =
|
|
||||||
'<i class="fas fa-check-circle" aria-hidden="true"></i>';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
helpTextElement.textContent = `Matching Document: $${responseJSON.dynamicsGPDocument.documentTotal.toFixed(2)}`;
|
|
||||||
iconElement.innerHTML =
|
|
||||||
'<i class="fas fa-exclamation-triangle" aria-hidden="true"></i>';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
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', '<span class="icon is-small is-right"></span>');
|
|
||||||
externalReceiptNumberControlElement.insertAdjacentHTML('afterend', '<p class="help has-text-right"></p>');
|
|
||||||
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();
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1 +0,0 @@
|
||||||
export {};
|
|
||||||
|
|
@ -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 =
|
|
||||||
`<i class="fas fa-fw fa-${cityssm.escapeHTML(lotOccupancyOccupant.fontAwesomeIconClass ?? '')}" aria-hidden="true"></i>`;
|
|
||||||
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 =
|
|
||||||
`<i class="fas fa-fw fa-${cityssm.escapeHTML(fontAwesomeIconClass)}" aria-hidden="true"></i>`;
|
|
||||||
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 = `<div class="message is-warning">
|
|
||||||
<p class="message-body">There are no ${los.escapedAliases.occupants} associated with this record.</p>
|
|
||||||
</div>`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const tableElement = document.createElement('table');
|
|
||||||
tableElement.className = 'table is-fullwidth is-striped is-hoverable';
|
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
|
||||||
tableElement.innerHTML = `<thead><tr>
|
|
||||||
<th>${los.escapedAliases.Occupant}</th>
|
|
||||||
<th>Address</th>
|
|
||||||
<th>Other Contact</th>
|
|
||||||
<th>Comment</th>
|
|
||||||
<th class="is-hidden-print"><span class="is-sr-only">Options</span></th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>`;
|
|
||||||
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 = `<td>
|
|
||||||
${cityssm.escapeHTML((lotOccupancyOccupant.occupantName ?? '') === '' &&
|
|
||||||
(lotOccupancyOccupant.occupantFamilyName ?? '') === ''
|
|
||||||
? '(No Name)'
|
|
||||||
: `${lotOccupancyOccupant.occupantName} ${lotOccupancyOccupant.occupantFamilyName}`)}<br />
|
|
||||||
<span class="tag">
|
|
||||||
<i class="fas fa-fw fa-${cityssm.escapeHTML(lotOccupancyOccupant.fontAwesomeIconClass ?? '')}" aria-hidden="true"></i>
|
|
||||||
<span class="ml-1">${cityssm.escapeHTML(lotOccupancyOccupant.lotOccupantType ?? '')}</span>
|
|
||||||
</span>
|
|
||||||
</td><td>
|
|
||||||
${(lotOccupancyOccupant.occupantAddress1 ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress1 ?? '')}<br />`}
|
|
||||||
${(lotOccupancyOccupant.occupantAddress2 ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress2 ?? '')}<br />`}
|
|
||||||
${(lotOccupancyOccupant.occupantCity ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: `${cityssm.escapeHTML(lotOccupancyOccupant.occupantCity ?? '')}, `}
|
|
||||||
${cityssm.escapeHTML(lotOccupancyOccupant.occupantProvince ?? '')}<br />
|
|
||||||
${cityssm.escapeHTML(lotOccupancyOccupant.occupantPostalCode ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${(lotOccupancyOccupant.occupantPhoneNumber ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: `${cityssm.escapeHTML(lotOccupancyOccupant.occupantPhoneNumber ?? '')}<br />`}
|
|
||||||
${(lotOccupancyOccupant.occupantEmailAddress ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: cityssm.escapeHTML(lotOccupancyOccupant.occupantEmailAddress ?? '')}
|
|
||||||
</td><td>
|
|
||||||
<span data-tooltip="${cityssm.escapeHTML((lotOccupancyOccupant.occupantCommentTitle ?? '') === ''
|
|
||||||
? 'Comment'
|
|
||||||
: lotOccupancyOccupant.occupantCommentTitle ?? '')}">
|
|
||||||
${cityssm.escapeHTML(lotOccupancyOccupant.occupantComment ?? '')}
|
|
||||||
</span>
|
|
||||||
</td><td class="is-hidden-print">
|
|
||||||
<div class="buttons are-small is-justify-content-end">
|
|
||||||
<button class="button is-primary button--edit" type="button">
|
|
||||||
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
|
|
||||||
<span>Edit</span>
|
|
||||||
</button>
|
|
||||||
<button class="button is-light is-danger button--delete" data-tooltip="Delete ${los.escapedAliases.Occupant}" type="button" aria-label="Delete">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</td>`;
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">Enter a partial name or address in the search field above.</p>
|
|
||||||
</div>`;
|
|
||||||
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 = `<strong>
|
|
||||||
${cityssm.escapeHTML(occupant.occupantName ?? '')} ${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')}
|
|
||||||
</strong><br />
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column">
|
|
||||||
${cityssm.escapeHTML(occupant.occupantAddress1 ?? '')}<br />
|
|
||||||
${(occupant.occupantAddress2 ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: `${cityssm.escapeHTML(occupant.occupantAddress2 ?? '')}<br />`}${cityssm.escapeHTML(occupant.occupantCity ?? '')}, ${cityssm.escapeHTML(occupant.occupantProvince ?? '')}<br />
|
|
||||||
${cityssm.escapeHTML(occupant.occupantPostalCode ?? '')}
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
${(occupant.occupantPhoneNumber ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: `${cityssm.escapeHTML(occupant.occupantPhoneNumber ?? '')}<br />`}
|
|
||||||
${cityssm.escapeHTML(occupant.occupantEmailAddress ?? '')}<br />
|
|
||||||
</div>
|
|
||||||
</div>`;
|
|
||||||
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 =
|
|
||||||
`<i class="fas fa-fw fa-${cityssm.escapeHTML(fontAwesomeIconClass)}" aria-hidden="true"></i>`;
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -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<string, unknown>
|
|
||||||
|
|
||||||
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 =
|
|
||||||
`<i class="fas fa-fw fa-${cityssm.escapeHTML(lotOccupancyOccupant.fontAwesomeIconClass ?? '')}" aria-hidden="true"></i>`
|
|
||||||
;(
|
|
||||||
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 =
|
|
||||||
`<i class="fas fa-fw fa-${cityssm.escapeHTML(fontAwesomeIconClass)}" aria-hidden="true"></i>`
|
|
||||||
|
|
||||||
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 = `<div class="message is-warning">
|
|
||||||
<p class="message-body">There are no ${los.escapedAliases.occupants} associated with this record.</p>
|
|
||||||
</div>`
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const tableElement = document.createElement('table')
|
|
||||||
tableElement.className = 'table is-fullwidth is-striped is-hoverable'
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
|
||||||
tableElement.innerHTML = `<thead><tr>
|
|
||||||
<th>${los.escapedAliases.Occupant}</th>
|
|
||||||
<th>Address</th>
|
|
||||||
<th>Other Contact</th>
|
|
||||||
<th>Comment</th>
|
|
||||||
<th class="is-hidden-print"><span class="is-sr-only">Options</span></th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>`
|
|
||||||
|
|
||||||
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 = `<td>
|
|
||||||
${cityssm.escapeHTML(
|
|
||||||
(lotOccupancyOccupant.occupantName ?? '') === '' &&
|
|
||||||
(lotOccupancyOccupant.occupantFamilyName ?? '') === ''
|
|
||||||
? '(No Name)'
|
|
||||||
: `${lotOccupancyOccupant.occupantName} ${lotOccupancyOccupant.occupantFamilyName}`
|
|
||||||
)}<br />
|
|
||||||
<span class="tag">
|
|
||||||
<i class="fas fa-fw fa-${cityssm.escapeHTML(lotOccupancyOccupant.fontAwesomeIconClass ?? '')}" aria-hidden="true"></i>
|
|
||||||
<span class="ml-1">${cityssm.escapeHTML(lotOccupancyOccupant.lotOccupantType ?? '')}</span>
|
|
||||||
</span>
|
|
||||||
</td><td>
|
|
||||||
${
|
|
||||||
(lotOccupancyOccupant.occupantAddress1 ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress1 ?? '')}<br />`
|
|
||||||
}
|
|
||||||
${
|
|
||||||
(lotOccupancyOccupant.occupantAddress2 ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: `${cityssm.escapeHTML(lotOccupancyOccupant.occupantAddress2 ?? '')}<br />`
|
|
||||||
}
|
|
||||||
${
|
|
||||||
(lotOccupancyOccupant.occupantCity ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: `${cityssm.escapeHTML(lotOccupancyOccupant.occupantCity ?? '')}, `
|
|
||||||
}
|
|
||||||
${cityssm.escapeHTML(lotOccupancyOccupant.occupantProvince ?? '')}<br />
|
|
||||||
${cityssm.escapeHTML(lotOccupancyOccupant.occupantPostalCode ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${
|
|
||||||
(lotOccupancyOccupant.occupantPhoneNumber ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: `${cityssm.escapeHTML(
|
|
||||||
lotOccupancyOccupant.occupantPhoneNumber ?? ''
|
|
||||||
)}<br />`
|
|
||||||
}
|
|
||||||
${
|
|
||||||
(lotOccupancyOccupant.occupantEmailAddress ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: cityssm.escapeHTML(
|
|
||||||
lotOccupancyOccupant.occupantEmailAddress ?? ''
|
|
||||||
)
|
|
||||||
}
|
|
||||||
</td><td>
|
|
||||||
<span data-tooltip="${cityssm.escapeHTML(
|
|
||||||
(lotOccupancyOccupant.occupantCommentTitle ?? '') === ''
|
|
||||||
? 'Comment'
|
|
||||||
: lotOccupancyOccupant.occupantCommentTitle ?? ''
|
|
||||||
)}">
|
|
||||||
${cityssm.escapeHTML(lotOccupancyOccupant.occupantComment ?? '')}
|
|
||||||
</span>
|
|
||||||
</td><td class="is-hidden-print">
|
|
||||||
<div class="buttons are-small is-justify-content-end">
|
|
||||||
<button class="button is-primary button--edit" type="button">
|
|
||||||
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
|
|
||||||
<span>Edit</span>
|
|
||||||
</button>
|
|
||||||
<button class="button is-light is-danger button--delete" data-tooltip="Delete ${los.escapedAliases.Occupant}" type="button" aria-label="Delete">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</td>`
|
|
||||||
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">Enter a partial name or address in the search field above.</p>
|
|
||||||
</div>`
|
|
||||||
|
|
||||||
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 = `<strong>
|
|
||||||
${cityssm.escapeHTML(occupant.occupantName ?? '')} ${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')}
|
|
||||||
</strong><br />
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column">
|
|
||||||
${cityssm.escapeHTML(occupant.occupantAddress1 ?? '')}<br />
|
|
||||||
${
|
|
||||||
(occupant.occupantAddress2 ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: `${cityssm.escapeHTML(occupant.occupantAddress2 ?? '')}<br />`
|
|
||||||
}${cityssm.escapeHTML(occupant.occupantCity ?? '')}, ${cityssm.escapeHTML(occupant.occupantProvince ?? '')}<br />
|
|
||||||
${cityssm.escapeHTML(occupant.occupantPostalCode ?? '')}
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
${
|
|
||||||
(occupant.occupantPhoneNumber ?? '') === ''
|
|
||||||
? ''
|
|
||||||
: `${cityssm.escapeHTML(occupant.occupantPhoneNumber ?? '')}<br />`
|
|
||||||
}
|
|
||||||
${cityssm.escapeHTML(occupant.occupantEmailAddress ?? '')}<br />
|
|
||||||
</div>
|
|
||||||
</div>`
|
|
||||||
|
|
||||||
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 =
|
|
||||||
`<i class="fas fa-fw fa-${cityssm.escapeHTML(fontAwesomeIconClass)}" aria-hidden="true"></i>`
|
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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', `<div class="panel-block is-block">
|
|
||||||
${los.getLoadingParagraphHTML('Loading conflicting milestones...')}
|
|
||||||
</div>`);
|
|
||||||
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', `<div class="panel-block is-block">
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-5">
|
|
||||||
${cityssm.escapeHTML(milestone.workOrderMilestoneTime === 0 ? 'No Time' : milestone.workOrderMilestoneTimePeriodString ?? '')}<br />
|
|
||||||
<strong>${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')}</strong>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
${cityssm.escapeHTML(milestone.workOrderNumber ?? '')}<br />
|
|
||||||
<span class="is-size-7">
|
|
||||||
${cityssm.escapeHTML(milestone.workOrderDescription ?? '')}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>`);
|
|
||||||
}
|
|
||||||
if (workOrderMilestones.length === 0) {
|
|
||||||
targetPanelElement.insertAdjacentHTML('beforeend', `<div class="panel-block is-block">
|
|
||||||
<div class="message is-info">
|
|
||||||
<p class="message-body">
|
|
||||||
There are no milestones on other work orders scheduled for
|
|
||||||
${cityssm.escapeHTML(workOrderMilestoneDateString)}.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
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
|
|
||||||
? '<br /><strong>Note that this milestone is expected to be completed in the future.</strong>'
|
|
||||||
: ''}`,
|
|
||||||
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 = `<div class="columns is-mobile">
|
|
||||||
<div class="column is-narrow">
|
|
||||||
${milestone.workOrderMilestoneCompletionDate
|
|
||||||
? `<span class="button is-static"
|
|
||||||
data-tooltip="Completed ${milestone.workOrderMilestoneCompletionDateString}"
|
|
||||||
aria-label="Completed ${milestone.workOrderMilestoneCompletionDateString}">
|
|
||||||
<span class="icon is-small"><i class="fas fa-check" aria-hidden="true"></i></span>
|
|
||||||
</span>`
|
|
||||||
: `<button class="button button--completeMilestone" data-tooltip="Incomplete" type="button" aria-label="Incomplete">
|
|
||||||
<span class="icon is-small"><i class="far fa-square" aria-hidden="true"></i></span>
|
|
||||||
</button>`}
|
|
||||||
</div><div class="column">
|
|
||||||
${milestone.workOrderMilestoneTypeId
|
|
||||||
? `<strong>${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')}</strong><br />`
|
|
||||||
: ''}
|
|
||||||
${milestone.workOrderMilestoneDate === 0
|
|
||||||
? '<span class="has-text-grey">(No Set Date)</span>'
|
|
||||||
: milestone.workOrderMilestoneDateString}
|
|
||||||
${milestone.workOrderMilestoneTime
|
|
||||||
? ` ${milestone.workOrderMilestoneTimePeriodString}`
|
|
||||||
: ''}<br />
|
|
||||||
<span class="is-size-7">
|
|
||||||
${cityssm.escapeHTML(milestone.workOrderMilestoneDescription ?? '')}
|
|
||||||
</span>
|
|
||||||
</div><div class="column is-narrow">
|
|
||||||
<div class="dropdown is-right">
|
|
||||||
<div class="dropdown-trigger">
|
|
||||||
<button class="button is-small" data-tooltip="Options" type="button" aria-label="Options">
|
|
||||||
<i class="fas fa-ellipsis-v" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<div class="dropdown-content">
|
|
||||||
${milestone.workOrderMilestoneCompletionDate
|
|
||||||
? `<a class="dropdown-item button--reopenMilestone" href="#">
|
|
||||||
<span class="icon is-small"><i class="fas fa-times" aria-hidden="true"></i></span>
|
|
||||||
<span>Reopen Milestone</span>
|
|
||||||
</a>`
|
|
||||||
: `<a class="dropdown-item button--editMilestone" href="#">
|
|
||||||
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
|
|
||||||
<span>Edit Milestone</span>
|
|
||||||
</a>`}
|
|
||||||
<hr class="dropdown-divider" />
|
|
||||||
<a class="dropdown-item button--deleteMilestone" href="#">
|
|
||||||
<span class="icon is-small"><i class="fas fa-trash has-text-danger" aria-hidden="true"></i></span>
|
|
||||||
<span>Delete Milestone</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div></div>`;
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
@ -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<string, unknown>
|
|
||||||
;(() => {
|
|
||||||
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',
|
|
||||||
`<div class="panel-block is-block">
|
|
||||||
${los.getLoadingParagraphHTML('Loading conflicting milestones...')}
|
|
||||||
</div>`
|
|
||||||
)
|
|
||||||
|
|
||||||
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',
|
|
||||||
`<div class="panel-block is-block">
|
|
||||||
<div class="columns">
|
|
||||||
<div class="column is-5">
|
|
||||||
${cityssm.escapeHTML(milestone.workOrderMilestoneTime === 0 ? 'No Time' : milestone.workOrderMilestoneTimePeriodString ?? '')}<br />
|
|
||||||
<strong>${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')}</strong>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
${cityssm.escapeHTML(milestone.workOrderNumber ?? '')}<br />
|
|
||||||
<span class="is-size-7">
|
|
||||||
${cityssm.escapeHTML(milestone.workOrderDescription ?? '')}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (workOrderMilestones.length === 0) {
|
|
||||||
targetPanelElement.insertAdjacentHTML(
|
|
||||||
'beforeend',
|
|
||||||
`<div class="panel-block is-block">
|
|
||||||
<div class="message is-info">
|
|
||||||
<p class="message-body">
|
|
||||||
There are no milestones on other work orders scheduled for
|
|
||||||
${cityssm.escapeHTML(workOrderMilestoneDateString)}.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
? '<br /><strong>Note that this milestone is expected to be completed in the future.</strong>'
|
|
||||||
: ''
|
|
||||||
}`,
|
|
||||||
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 = `<div class="columns is-mobile">
|
|
||||||
<div class="column is-narrow">
|
|
||||||
${
|
|
||||||
milestone.workOrderMilestoneCompletionDate
|
|
||||||
? `<span class="button is-static"
|
|
||||||
data-tooltip="Completed ${milestone.workOrderMilestoneCompletionDateString}"
|
|
||||||
aria-label="Completed ${milestone.workOrderMilestoneCompletionDateString}">
|
|
||||||
<span class="icon is-small"><i class="fas fa-check" aria-hidden="true"></i></span>
|
|
||||||
</span>`
|
|
||||||
: `<button class="button button--completeMilestone" data-tooltip="Incomplete" type="button" aria-label="Incomplete">
|
|
||||||
<span class="icon is-small"><i class="far fa-square" aria-hidden="true"></i></span>
|
|
||||||
</button>`
|
|
||||||
}
|
|
||||||
</div><div class="column">
|
|
||||||
${
|
|
||||||
milestone.workOrderMilestoneTypeId
|
|
||||||
? `<strong>${cityssm.escapeHTML(milestone.workOrderMilestoneType ?? '')}</strong><br />`
|
|
||||||
: ''
|
|
||||||
}
|
|
||||||
${
|
|
||||||
milestone.workOrderMilestoneDate === 0
|
|
||||||
? '<span class="has-text-grey">(No Set Date)</span>'
|
|
||||||
: milestone.workOrderMilestoneDateString
|
|
||||||
}
|
|
||||||
${
|
|
||||||
milestone.workOrderMilestoneTime
|
|
||||||
? ` ${milestone.workOrderMilestoneTimePeriodString}`
|
|
||||||
: ''
|
|
||||||
}<br />
|
|
||||||
<span class="is-size-7">
|
|
||||||
${cityssm.escapeHTML(milestone.workOrderMilestoneDescription ?? '')}
|
|
||||||
</span>
|
|
||||||
</div><div class="column is-narrow">
|
|
||||||
<div class="dropdown is-right">
|
|
||||||
<div class="dropdown-trigger">
|
|
||||||
<button class="button is-small" data-tooltip="Options" type="button" aria-label="Options">
|
|
||||||
<i class="fas fa-ellipsis-v" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<div class="dropdown-content">
|
|
||||||
${
|
|
||||||
milestone.workOrderMilestoneCompletionDate
|
|
||||||
? `<a class="dropdown-item button--reopenMilestone" href="#">
|
|
||||||
<span class="icon is-small"><i class="fas fa-times" aria-hidden="true"></i></span>
|
|
||||||
<span>Reopen Milestone</span>
|
|
||||||
</a>`
|
|
||||||
: `<a class="dropdown-item button--editMilestone" href="#">
|
|
||||||
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
|
|
||||||
<span>Edit Milestone</span>
|
|
||||||
</a>`
|
|
||||||
}
|
|
||||||
<hr class="dropdown-divider" />
|
|
||||||
<a class="dropdown-item button--deleteMilestone" href="#">
|
|
||||||
<span class="icon is-small"><i class="fas fa-trash has-text-danger" aria-hidden="true"></i></span>
|
|
||||||
<span>Delete Milestone</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div></div>`
|
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export {};
|
|
||||||
|
|
@ -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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no comments to display.</p>
|
|
||||||
</div>`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const tableElement = document.createElement('table');
|
|
||||||
tableElement.className = 'table is-fullwidth is-striped is-hoverable';
|
|
||||||
tableElement.innerHTML = `<thead><tr>
|
|
||||||
<th>Commentor</th>
|
|
||||||
<th>Comment Date</th>
|
|
||||||
<th>Comment</th>
|
|
||||||
<th class="is-hidden-print"><span class="is-sr-only">Options</span></th></tr></thead><tbody></tbody>`;
|
|
||||||
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 = `<td>
|
|
||||||
${cityssm.escapeHTML(workOrderComment.recordCreate_userName ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${workOrderComment.workOrderCommentDateString}
|
|
||||||
${workOrderComment.workOrderCommentTime === 0
|
|
||||||
? ''
|
|
||||||
: workOrderComment.workOrderCommentTimePeriodString}
|
|
||||||
</td><td>
|
|
||||||
${cityssm.escapeHTML(workOrderComment.workOrderComment ?? '')}
|
|
||||||
</td><td class="is-hidden-print">
|
|
||||||
<div class="buttons are-small is-justify-content-end">
|
|
||||||
<button class="button is-primary button--edit" type="button">
|
|
||||||
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
|
|
||||||
<span>Edit</span>
|
|
||||||
</button>
|
|
||||||
<button class="button is-light is-danger button--delete" data-tooltip="Delete Comment" type="button" aria-label="Delete">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</td>`;
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
@ -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<string, unknown>
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no comments to display.</p>
|
|
||||||
</div>`
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const tableElement = document.createElement('table')
|
|
||||||
tableElement.className = 'table is-fullwidth is-striped is-hoverable'
|
|
||||||
tableElement.innerHTML = `<thead><tr>
|
|
||||||
<th>Commentor</th>
|
|
||||||
<th>Comment Date</th>
|
|
||||||
<th>Comment</th>
|
|
||||||
<th class="is-hidden-print"><span class="is-sr-only">Options</span></th></tr></thead><tbody></tbody>`
|
|
||||||
|
|
||||||
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 = `<td>
|
|
||||||
${cityssm.escapeHTML(workOrderComment.recordCreate_userName ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${workOrderComment.workOrderCommentDateString}
|
|
||||||
${
|
|
||||||
workOrderComment.workOrderCommentTime === 0
|
|
||||||
? ''
|
|
||||||
: workOrderComment.workOrderCommentTimePeriodString
|
|
||||||
}
|
|
||||||
</td><td>
|
|
||||||
${cityssm.escapeHTML(workOrderComment.workOrderComment ?? '')}
|
|
||||||
</td><td class="is-hidden-print">
|
|
||||||
<div class="buttons are-small is-justify-content-end">
|
|
||||||
<button class="button is-primary button--edit" type="button">
|
|
||||||
<span class="icon is-small"><i class="fas fa-pencil-alt" aria-hidden="true"></i></span>
|
|
||||||
<span>Edit</span>
|
|
||||||
</button>
|
|
||||||
<button class="button is-light is-danger button--delete" data-tooltip="Delete Comment" type="button" aria-label="Delete">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</td>`
|
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
export {};
|
|
||||||
|
|
@ -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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no ${los.escapedAliases.occupancies} associated with this work order.</p>
|
|
||||||
</div>`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
|
||||||
occupanciesContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable">
|
|
||||||
<thead><tr>
|
|
||||||
<th class="has-width-1"></th>
|
|
||||||
<th>${los.escapedAliases.Occupancy} Type</th>
|
|
||||||
<th>${los.escapedAliases.Lot}</th>
|
|
||||||
<th>${los.escapedAliases.OccupancyStartDate}</th>
|
|
||||||
<th>End Date</th>
|
|
||||||
<th>${los.escapedAliases.Occupants}</th>
|
|
||||||
<th class="has-width-1"></th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>`;
|
|
||||||
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 = `<td class="is-width-1 has-text-centered">
|
|
||||||
${isActive
|
|
||||||
? `<i class="fas fa-play" title="Current ${los.escapedAliases.Occupancy}"></i>`
|
|
||||||
: `<i class="fas fa-stop" title="Previous ${los.escapedAliases.Occupancy}"></i>`}
|
|
||||||
</td><td>
|
|
||||||
<a class="has-text-weight-bold" href="${los.getLotOccupancyURL(lotOccupancy.lotOccupancyId)}">
|
|
||||||
${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')}
|
|
||||||
</a><br />
|
|
||||||
<span class="is-size-7">#${lotOccupancy.lotOccupancyId}</span>
|
|
||||||
</td>`;
|
|
||||||
if (lotOccupancy.lotId) {
|
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
|
||||||
rowElement.insertAdjacentHTML('beforeend', `<td>
|
|
||||||
${cityssm.escapeHTML(lotOccupancy.lotName ?? '')}
|
|
||||||
${hasLotRecord
|
|
||||||
? ''
|
|
||||||
: ` <button class="button is-small is-light is-success button--addLot"
|
|
||||||
data-lot-id="${lotOccupancy.lotId.toString()}"
|
|
||||||
data-tooltip="Add ${los.escapedAliases.Lot}"
|
|
||||||
aria-label="Add ${los.escapedAliases.Lot}" type="button">
|
|
||||||
<i class="fas fa-plus" aria-hidden="true"></i>
|
|
||||||
</button>`}
|
|
||||||
</td>`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
|
||||||
rowElement.insertAdjacentHTML('beforeend', `<td><span class="has-text-grey">(No ${los.escapedAliases.Lot})</span></td>`);
|
|
||||||
}
|
|
||||||
let occupantsHTML = '';
|
|
||||||
for (const occupant of lotOccupancy.lotOccupancyOccupants) {
|
|
||||||
occupantsHTML += `<li class="has-tooltip-left"
|
|
||||||
data-tooltip="${cityssm.escapeHTML(occupant.lotOccupantType ?? '')}">
|
|
||||||
<span class="fa-li">
|
|
||||||
<i class="fas fa-fw fa-${cityssm.escapeHTML((occupant.fontAwesomeIconClass ?? '') === ''
|
|
||||||
? 'user'
|
|
||||||
: occupant.fontAwesomeIconClass ?? '')}" aria-label="${los.escapedAliases.Occupant}"></i>
|
|
||||||
</span>
|
|
||||||
${cityssm.escapeHTML(occupant.occupantName ?? '')}
|
|
||||||
${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')}
|
|
||||||
</li>`;
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
|
||||||
rowElement.insertAdjacentHTML('beforeend', `<td>
|
|
||||||
${lotOccupancy.occupancyStartDateString}
|
|
||||||
</td><td>
|
|
||||||
${lotOccupancy.occupancyEndDate
|
|
||||||
? lotOccupancy.occupancyEndDateString
|
|
||||||
: '<span class="has-text-grey">(No End Date)</span>'}
|
|
||||||
</td><td>
|
|
||||||
${lotOccupancy.lotOccupancyOccupants.length === 0
|
|
||||||
? `<span class="has-text-grey">(No ${los.escapedAliases.Occupants})</span>`
|
|
||||||
: `<ul class="fa-ul ml-5">${occupantsHTML}</ul>`}
|
|
||||||
</td><td>
|
|
||||||
<button class="button is-small is-light is-danger button--deleteLotOccupancy" data-tooltip="Delete Relationship" type="button">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</td>`);
|
|
||||||
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', `<input name="workOrderId" type="hidden" value="${workOrderId}" />`);
|
|
||||||
},
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no ${los.escapedAliases.lots} associated with this work order.</p>
|
|
||||||
</div>`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
|
||||||
lotsContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable">
|
|
||||||
<thead><tr>
|
|
||||||
<th>${los.escapedAliases.Lot}</th>
|
|
||||||
<th>${los.escapedAliases.Map}</th>
|
|
||||||
<th>${los.escapedAliases.Lot} Type</th>
|
|
||||||
<th>Status</th>
|
|
||||||
<th class="has-width-1"></th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>`;
|
|
||||||
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 = `<td>
|
|
||||||
<a class="has-text-weight-bold" href="${los.getLotURL(lot.lotId)}">
|
|
||||||
${cityssm.escapeHTML(lot.lotName ?? '')}
|
|
||||||
</a>
|
|
||||||
</td><td>
|
|
||||||
${cityssm.escapeHTML(lot.mapName ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${cityssm.escapeHTML(lot.lotType ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${lot.lotStatusId
|
|
||||||
? cityssm.escapeHTML(lot.lotStatus ?? '')
|
|
||||||
: '<span class="has-text-grey">(No Status)</span>'}
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<button class="button is-small is-light is-info button--editLotStatus" data-tooltip="Update Status" type="button">
|
|
||||||
<i class="fas fa-pencil-alt" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
<button class="button is-small is-light is-danger button--deleteLot" data-tooltip="Delete Relationship" type="button">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</td>`;
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no records that meet the search criteria.</p>
|
|
||||||
</div>`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
|
||||||
searchResultsContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable">
|
|
||||||
<thead><tr>
|
|
||||||
<th class="has-width-1"></th>
|
|
||||||
<th>${los.escapedAliases.Occupancy} Type</th>
|
|
||||||
<th>${los.escapedAliases.Lot}</th>
|
|
||||||
<th>${los.escapedAliases.OccupancyStartDate}</th>
|
|
||||||
<th>End Date</th>
|
|
||||||
<th>${los.escapedAliases.Occupants}</th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>`;
|
|
||||||
for (const lotOccupancy of responseJSON.lotOccupancies) {
|
|
||||||
const rowElement = document.createElement('tr');
|
|
||||||
rowElement.className = 'container--lotOccupancy';
|
|
||||||
rowElement.dataset.lotOccupancyId =
|
|
||||||
lotOccupancy.lotOccupancyId.toString();
|
|
||||||
rowElement.innerHTML = `<td class="has-text-centered">
|
|
||||||
<button class="button is-small is-success button--addLotOccupancy" data-tooltip="Add" type="button" aria-label="Add">
|
|
||||||
<i class="fas fa-plus" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
<td class="has-text-weight-bold">
|
|
||||||
${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')}
|
|
||||||
</td>`;
|
|
||||||
if (lotOccupancy.lotId) {
|
|
||||||
rowElement.insertAdjacentHTML('beforeend', `<td>${cityssm.escapeHTML(lotOccupancy.lotName ?? '')}</td>`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
|
||||||
rowElement.insertAdjacentHTML('beforeend', `<td><span class="has-text-grey">(No ${los.escapedAliases.Lot})</span></td>`);
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
|
||||||
rowElement.insertAdjacentHTML('beforeend', `<td>
|
|
||||||
${lotOccupancy.occupancyStartDateString}
|
|
||||||
</td><td>
|
|
||||||
${lotOccupancy.occupancyEndDate
|
|
||||||
? lotOccupancy.occupancyEndDateString
|
|
||||||
: '<span class="has-text-grey">(No End Date)</span>'}
|
|
||||||
</td><td>
|
|
||||||
${lotOccupancy.lotOccupancyOccupants.length === 0
|
|
||||||
? `<span class="has-text-grey">
|
|
||||||
(No ${cityssm.escapeHTML(los.escapedAliases.Occupants)})
|
|
||||||
</span>`
|
|
||||||
: cityssm.escapeHTML(`${lotOccupancy.lotOccupancyOccupants[0].occupantName}
|
|
||||||
${lotOccupancy.lotOccupancyOccupants[0]
|
|
||||||
.occupantFamilyName}`) +
|
|
||||||
(lotOccupancy.lotOccupancyOccupants.length > 1
|
|
||||||
? ` plus
|
|
||||||
${(lotOccupancy.lotOccupancyOccupants.length - 1).toString()}`
|
|
||||||
: '')}</td>`);
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no records that meet the search criteria.</p>
|
|
||||||
</div>`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
|
||||||
searchResultsContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable">
|
|
||||||
<thead><tr>
|
|
||||||
<th class="has-width-1"></th>
|
|
||||||
<th>${los.escapedAliases.Lot}</th>
|
|
||||||
<th>${los.escapedAliases.Map}</th>
|
|
||||||
<th>${los.escapedAliases.Lot} Type</th>
|
|
||||||
<th>Status</th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>`;
|
|
||||||
for (const lot of responseJSON.lots) {
|
|
||||||
const rowElement = document.createElement('tr');
|
|
||||||
rowElement.className = 'container--lot';
|
|
||||||
rowElement.dataset.lotId = lot.lotId.toString();
|
|
||||||
rowElement.innerHTML = `<td class="has-text-centered">
|
|
||||||
<button class="button is-small is-success button--addLot" data-tooltip="Add" type="button" aria-label="Add">
|
|
||||||
<i class="fas fa-plus" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</td><td class="has-text-weight-bold">
|
|
||||||
${cityssm.escapeHTML(lot.lotName ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${cityssm.escapeHTML(lot.mapName ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${cityssm.escapeHTML(lot.lotType ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${cityssm.escapeHTML(lot.lotStatus ?? '')}
|
|
||||||
</td>`;
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
@ -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<string, unknown>
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no ${los.escapedAliases.occupancies} associated with this work order.</p>
|
|
||||||
</div>`
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
|
||||||
occupanciesContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable">
|
|
||||||
<thead><tr>
|
|
||||||
<th class="has-width-1"></th>
|
|
||||||
<th>${los.escapedAliases.Occupancy} Type</th>
|
|
||||||
<th>${los.escapedAliases.Lot}</th>
|
|
||||||
<th>${los.escapedAliases.OccupancyStartDate}</th>
|
|
||||||
<th>End Date</th>
|
|
||||||
<th>${los.escapedAliases.Occupants}</th>
|
|
||||||
<th class="has-width-1"></th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>`
|
|
||||||
|
|
||||||
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 = `<td class="is-width-1 has-text-centered">
|
|
||||||
${
|
|
||||||
isActive
|
|
||||||
? `<i class="fas fa-play" title="Current ${los.escapedAliases.Occupancy}"></i>`
|
|
||||||
: `<i class="fas fa-stop" title="Previous ${los.escapedAliases.Occupancy}"></i>`
|
|
||||||
}
|
|
||||||
</td><td>
|
|
||||||
<a class="has-text-weight-bold" href="${los.getLotOccupancyURL(lotOccupancy.lotOccupancyId)}">
|
|
||||||
${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')}
|
|
||||||
</a><br />
|
|
||||||
<span class="is-size-7">#${lotOccupancy.lotOccupancyId}</span>
|
|
||||||
</td>`
|
|
||||||
|
|
||||||
if (lotOccupancy.lotId) {
|
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
|
||||||
rowElement.insertAdjacentHTML(
|
|
||||||
'beforeend',
|
|
||||||
`<td>
|
|
||||||
${cityssm.escapeHTML(lotOccupancy.lotName ?? '')}
|
|
||||||
${
|
|
||||||
hasLotRecord
|
|
||||||
? ''
|
|
||||||
: ` <button class="button is-small is-light is-success button--addLot"
|
|
||||||
data-lot-id="${lotOccupancy.lotId.toString()}"
|
|
||||||
data-tooltip="Add ${los.escapedAliases.Lot}"
|
|
||||||
aria-label="Add ${los.escapedAliases.Lot}" type="button">
|
|
||||||
<i class="fas fa-plus" aria-hidden="true"></i>
|
|
||||||
</button>`
|
|
||||||
}
|
|
||||||
</td>`
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
|
||||||
rowElement.insertAdjacentHTML(
|
|
||||||
'beforeend',
|
|
||||||
`<td><span class="has-text-grey">(No ${los.escapedAliases.Lot})</span></td>`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
let occupantsHTML = ''
|
|
||||||
|
|
||||||
for (const occupant of lotOccupancy.lotOccupancyOccupants!) {
|
|
||||||
occupantsHTML += `<li class="has-tooltip-left"
|
|
||||||
data-tooltip="${cityssm.escapeHTML(occupant.lotOccupantType ?? '')}">
|
|
||||||
<span class="fa-li">
|
|
||||||
<i class="fas fa-fw fa-${cityssm.escapeHTML(
|
|
||||||
(occupant.fontAwesomeIconClass ?? '') === ''
|
|
||||||
? 'user'
|
|
||||||
: occupant.fontAwesomeIconClass ?? ''
|
|
||||||
)}" aria-label="${los.escapedAliases.Occupant}"></i>
|
|
||||||
</span>
|
|
||||||
${cityssm.escapeHTML(occupant.occupantName ?? '')}
|
|
||||||
${cityssm.escapeHTML(occupant.occupantFamilyName ?? '')}
|
|
||||||
</li>`
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
|
||||||
rowElement.insertAdjacentHTML(
|
|
||||||
'beforeend',
|
|
||||||
`<td>
|
|
||||||
${lotOccupancy.occupancyStartDateString}
|
|
||||||
</td><td>
|
|
||||||
${
|
|
||||||
lotOccupancy.occupancyEndDate
|
|
||||||
? lotOccupancy.occupancyEndDateString
|
|
||||||
: '<span class="has-text-grey">(No End Date)</span>'
|
|
||||||
}
|
|
||||||
</td><td>
|
|
||||||
${
|
|
||||||
lotOccupancy.lotOccupancyOccupants!.length === 0
|
|
||||||
? `<span class="has-text-grey">(No ${los.escapedAliases.Occupants})</span>`
|
|
||||||
: `<ul class="fa-ul ml-5">${occupantsHTML}</ul>`
|
|
||||||
}
|
|
||||||
</td><td>
|
|
||||||
<button class="button is-small is-light is-danger button--deleteLotOccupancy" data-tooltip="Delete Relationship" type="button">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</td>`
|
|
||||||
)
|
|
||||||
|
|
||||||
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',
|
|
||||||
`<input name="workOrderId" type="hidden" value="${workOrderId}" />`
|
|
||||||
)
|
|
||||||
},
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no ${los.escapedAliases.lots} associated with this work order.</p>
|
|
||||||
</div>`
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
|
||||||
lotsContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable">
|
|
||||||
<thead><tr>
|
|
||||||
<th>${los.escapedAliases.Lot}</th>
|
|
||||||
<th>${los.escapedAliases.Map}</th>
|
|
||||||
<th>${los.escapedAliases.Lot} Type</th>
|
|
||||||
<th>Status</th>
|
|
||||||
<th class="has-width-1"></th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>`
|
|
||||||
|
|
||||||
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 = `<td>
|
|
||||||
<a class="has-text-weight-bold" href="${los.getLotURL(lot.lotId)}">
|
|
||||||
${cityssm.escapeHTML(lot.lotName ?? '')}
|
|
||||||
</a>
|
|
||||||
</td><td>
|
|
||||||
${cityssm.escapeHTML(lot.mapName ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${cityssm.escapeHTML(lot.lotType ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${
|
|
||||||
lot.lotStatusId
|
|
||||||
? cityssm.escapeHTML(lot.lotStatus ?? '')
|
|
||||||
: '<span class="has-text-grey">(No Status)</span>'
|
|
||||||
}
|
|
||||||
</td><td class="is-nowrap">
|
|
||||||
<button class="button is-small is-light is-info button--editLotStatus" data-tooltip="Update Status" type="button">
|
|
||||||
<i class="fas fa-pencil-alt" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
<button class="button is-small is-light is-danger button--deleteLot" data-tooltip="Delete Relationship" type="button">
|
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</td>`
|
|
||||||
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no records that meet the search criteria.</p>
|
|
||||||
</div>`
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
|
||||||
searchResultsContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable">
|
|
||||||
<thead><tr>
|
|
||||||
<th class="has-width-1"></th>
|
|
||||||
<th>${los.escapedAliases.Occupancy} Type</th>
|
|
||||||
<th>${los.escapedAliases.Lot}</th>
|
|
||||||
<th>${los.escapedAliases.OccupancyStartDate}</th>
|
|
||||||
<th>End Date</th>
|
|
||||||
<th>${los.escapedAliases.Occupants}</th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>`
|
|
||||||
|
|
||||||
for (const lotOccupancy of responseJSON.lotOccupancies) {
|
|
||||||
const rowElement = document.createElement('tr')
|
|
||||||
rowElement.className = 'container--lotOccupancy'
|
|
||||||
rowElement.dataset.lotOccupancyId =
|
|
||||||
lotOccupancy.lotOccupancyId.toString()
|
|
||||||
|
|
||||||
rowElement.innerHTML = `<td class="has-text-centered">
|
|
||||||
<button class="button is-small is-success button--addLotOccupancy" data-tooltip="Add" type="button" aria-label="Add">
|
|
||||||
<i class="fas fa-plus" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
<td class="has-text-weight-bold">
|
|
||||||
${cityssm.escapeHTML(lotOccupancy.occupancyType ?? '')}
|
|
||||||
</td>`
|
|
||||||
|
|
||||||
if (lotOccupancy.lotId) {
|
|
||||||
rowElement.insertAdjacentHTML(
|
|
||||||
'beforeend',
|
|
||||||
`<td>${cityssm.escapeHTML(lotOccupancy.lotName ?? '')}</td>`
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
|
||||||
rowElement.insertAdjacentHTML(
|
|
||||||
'beforeend',
|
|
||||||
`<td><span class="has-text-grey">(No ${los.escapedAliases.Lot})</span></td>`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-unsanitized/method
|
|
||||||
rowElement.insertAdjacentHTML(
|
|
||||||
'beforeend',
|
|
||||||
`<td>
|
|
||||||
${lotOccupancy.occupancyStartDateString}
|
|
||||||
</td><td>
|
|
||||||
${
|
|
||||||
lotOccupancy.occupancyEndDate
|
|
||||||
? lotOccupancy.occupancyEndDateString
|
|
||||||
: '<span class="has-text-grey">(No End Date)</span>'
|
|
||||||
}
|
|
||||||
</td><td>
|
|
||||||
${
|
|
||||||
lotOccupancy.lotOccupancyOccupants!.length === 0
|
|
||||||
? `<span class="has-text-grey">
|
|
||||||
(No ${cityssm.escapeHTML(
|
|
||||||
los.escapedAliases.Occupants
|
|
||||||
)})
|
|
||||||
</span>`
|
|
||||||
: cityssm.escapeHTML(
|
|
||||||
`${lotOccupancy.lotOccupancyOccupants![0].occupantName}
|
|
||||||
${
|
|
||||||
lotOccupancy.lotOccupancyOccupants![0]
|
|
||||||
.occupantFamilyName
|
|
||||||
}`
|
|
||||||
) +
|
|
||||||
(lotOccupancy.lotOccupancyOccupants!.length > 1
|
|
||||||
? ` plus
|
|
||||||
${(
|
|
||||||
lotOccupancy.lotOccupancyOccupants!.length - 1
|
|
||||||
).toString()}`
|
|
||||||
: '')
|
|
||||||
}</td>`
|
|
||||||
)
|
|
||||||
|
|
||||||
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 = `<div class="message is-info">
|
|
||||||
<p class="message-body">There are no records that meet the search criteria.</p>
|
|
||||||
</div>`
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
|
||||||
searchResultsContainerElement.innerHTML = `<table class="table is-fullwidth is-striped is-hoverable">
|
|
||||||
<thead><tr>
|
|
||||||
<th class="has-width-1"></th>
|
|
||||||
<th>${los.escapedAliases.Lot}</th>
|
|
||||||
<th>${los.escapedAliases.Map}</th>
|
|
||||||
<th>${los.escapedAliases.Lot} Type</th>
|
|
||||||
<th>Status</th>
|
|
||||||
</tr></thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>`
|
|
||||||
|
|
||||||
for (const lot of responseJSON.lots) {
|
|
||||||
const rowElement = document.createElement('tr')
|
|
||||||
rowElement.className = 'container--lot'
|
|
||||||
rowElement.dataset.lotId = lot.lotId.toString()
|
|
||||||
|
|
||||||
rowElement.innerHTML = `<td class="has-text-centered">
|
|
||||||
<button class="button is-small is-success button--addLot" data-tooltip="Add" type="button" aria-label="Add">
|
|
||||||
<i class="fas fa-plus" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</td><td class="has-text-weight-bold">
|
|
||||||
${cityssm.escapeHTML(lot.lotName ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${cityssm.escapeHTML(lot.mapName ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${cityssm.escapeHTML(lot.lotType ?? '')}
|
|
||||||
</td><td>
|
|
||||||
${cityssm.escapeHTML(lot.lotStatus ?? '')}
|
|
||||||
</td>`
|
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
@ -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 <strong>${t.fileName}</strong><br />\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}})})})();
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
import type { BulmaJS } from '@cityssm/bulma-js/types.js'
|
import type { BulmaJS } from '@cityssm/bulma-js/types.js'
|
||||||
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/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 cityssm: cityssmGlobal
|
||||||
declare const bulmaJS: BulmaJS
|
declare const bulmaJS: BulmaJS
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -4,13 +4,13 @@
|
||||||
import type { BulmaJS } from '@cityssm/bulma-js/types.js'
|
import type { BulmaJS } from '@cityssm/bulma-js/types.js'
|
||||||
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/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 {
|
import type {
|
||||||
Fee,
|
Fee,
|
||||||
FeeCategory,
|
FeeCategory,
|
||||||
LotType,
|
LotType,
|
||||||
OccupancyType
|
OccupancyType
|
||||||
} from '../types/recordTypes.js'
|
} from '../../types/recordTypes.js'
|
||||||
|
|
||||||
declare const cityssm: cityssmGlobal
|
declare const cityssm: cityssmGlobal
|
||||||
declare const bulmaJS: BulmaJS
|
declare const bulmaJS: BulmaJS
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -4,8 +4,8 @@
|
||||||
import type { BulmaJS } from '@cityssm/bulma-js/types.js'
|
import type { BulmaJS } from '@cityssm/bulma-js/types.js'
|
||||||
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/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 { LotType, LotTypeField } from '../types/recordTypes.js'
|
import type { LotType, LotTypeField } from '../../types/recordTypes.js'
|
||||||
|
|
||||||
declare const cityssm: cityssmGlobal
|
declare const cityssm: cityssmGlobal
|
||||||
declare const bulmaJS: BulmaJS
|
declare const bulmaJS: BulmaJS
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -4,8 +4,8 @@
|
||||||
import type { BulmaJS } from '@cityssm/bulma-js/types.js'
|
import type { BulmaJS } from '@cityssm/bulma-js/types.js'
|
||||||
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/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 { OccupancyType, OccupancyTypeField } from '../types/recordTypes.js'
|
import type { OccupancyType, OccupancyTypeField } from '../../types/recordTypes.js'
|
||||||
|
|
||||||
declare const cityssm: cityssmGlobal
|
declare const cityssm: cityssmGlobal
|
||||||
declare const bulmaJS: BulmaJS
|
declare const bulmaJS: BulmaJS
|
||||||
|
|
@ -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 =
|
||||||
|
`<i class="fas fa-fw fa-${fontAwesomeIconClass}" aria-hidden="true"></i>`;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 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?<br />
|
||||||
|
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 = `<tr><td colspan="2">
|
||||||
|
<div class="message is-warning"><p class="message-body">There are no active work order types.</p></div>
|
||||||
|
</td></tr>`;
|
||||||
|
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 = `<td>
|
||||||
|
<form>
|
||||||
|
<input name="workOrderTypeId" type="hidden" value="${workOrderType.workOrderTypeId.toString()}" />
|
||||||
|
<div class="field has-addons">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" name="workOrderType" type="text"
|
||||||
|
value="${cityssm.escapeHTML(workOrderType.workOrderType ?? '')}" maxlength="100" aria-label="Work Order Type" required />
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-success" type="submit" aria-label="Save">
|
||||||
|
<i class="fas fa-save" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</td><td class="is-nowrap">
|
||||||
|
<div class="field is-grouped">
|
||||||
|
<div class="control">
|
||||||
|
${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderTypeUp', 'button--moveWorkOrderTypeDown', false)}
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-danger is-light button--deleteWorkOrderType" data-tooltip="Delete Work Order Type" type="button" aria-label="Delete Work Order Type">
|
||||||
|
<i class="fas fa-trash" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>`;
|
||||||
|
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?<br />
|
||||||
|
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 = `<tr><td colspan="2">
|
||||||
|
<div class="message is-warning"><p class="message-body">There are no active work order milestone types.</p></div>
|
||||||
|
</td></tr>`;
|
||||||
|
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 = `<td>
|
||||||
|
<form>
|
||||||
|
<input name="workOrderMilestoneTypeId" type="hidden" value="${workOrderMilestoneType.workOrderMilestoneTypeId.toString()}" />
|
||||||
|
<div class="field has-addons">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" name="workOrderMilestoneType" type="text"
|
||||||
|
value="${cityssm.escapeHTML(workOrderMilestoneType.workOrderMilestoneType)}" maxlength="100" aria-label="Work Order Milestone Type" required />
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-success" type="submit" aria-label="Save">
|
||||||
|
<i class="fas fa-save" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</td><td class="is-nowrap">
|
||||||
|
<div class="field is-grouped">
|
||||||
|
<div class="control">
|
||||||
|
${los.getMoveUpDownButtonFieldHTML('button--moveWorkOrderMilestoneTypeUp', 'button--moveWorkOrderMilestoneTypeDown', false)}
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-danger is-light button--deleteWorkOrderMilestoneType" data-tooltip="Delete Mielstone Type" type="button" aria-label="Delete Milestone Type">
|
||||||
|
<i class="fas fa-trash" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>`;
|
||||||
|
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?<br />
|
||||||
|
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 = `<tr><td colspan="2">
|
||||||
|
<div class="message is-warning"><p class="message-body">There are no active ${los.escapedAliases.lot} statuses.</p></div>
|
||||||
|
</td></tr>`;
|
||||||
|
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 = `<td>
|
||||||
|
<form>
|
||||||
|
<input name="lotStatusId" type="hidden" value="${lotStatus.lotStatusId.toString()}" />
|
||||||
|
<div class="field has-addons">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" name="lotStatus" type="text"
|
||||||
|
value="${cityssm.escapeHTML(lotStatus.lotStatus)}"
|
||||||
|
aria-label="${los.escapedAliases.Lot} Status" maxlength="100" required />
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-success" type="submit" aria-label="Save">
|
||||||
|
<i class="fas fa-save" aria-hidden="true"></i>\
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</td><td class="is-nowrap">
|
||||||
|
<div class="field is-grouped">
|
||||||
|
<div class="control">
|
||||||
|
${los.getMoveUpDownButtonFieldHTML('button--moveLotStatusUp', 'button--moveLotStatusDown', false)}
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-danger is-light button--deleteLotStatus" data-tooltip="Delete Status" type="button" aria-label="Delete Status">
|
||||||
|
<i class="fas fa-trash" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>`;
|
||||||
|
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?<br />
|
||||||
|
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 = `<tr><td colspan="3">
|
||||||
|
<div class="message is-warning">
|
||||||
|
<p class="message-body">There are no active ${los.escapedAliases.lot} ${los.escapedAliases.occupant} types.</p>
|
||||||
|
</div>
|
||||||
|
</td></tr>`;
|
||||||
|
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 = `<td>
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" name="lotOccupantType" type="text"
|
||||||
|
value="${cityssm.escapeHTML(lotOccupantType.lotOccupantType)}"
|
||||||
|
form="${formId}"
|
||||||
|
aria-label="${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type" maxlength="100" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td><td>
|
||||||
|
<div class="field has-addons">
|
||||||
|
<div class="control">
|
||||||
|
<span class="button is-static">fa-</span>
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" name="fontAwesomeIconClass" type="text"
|
||||||
|
value="${cityssm.escapeHTML(lotOccupantType.fontAwesomeIconClass)}"
|
||||||
|
form="${formId}"
|
||||||
|
list="datalist--fontAwesomeIconClass" aria-label="Icon Name" maxlength="50" />
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<span class="button is-static">
|
||||||
|
<i class="fas fa-fw fa-${cityssm.escapeHTML(lotOccupantType.fontAwesomeIconClass)}"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td><td>
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" name="occupantCommentTitle" type="text"
|
||||||
|
value="${cityssm.escapeHTML(lotOccupantType.occupantCommentTitle)}"
|
||||||
|
form="${formId}"
|
||||||
|
aria-label="${los.escapedAliases.Occupant} Comment Title" maxlength="50" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td><td>
|
||||||
|
<form id="${formId}">
|
||||||
|
<input name="lotOccupantTypeId" type="hidden"
|
||||||
|
value="${lotOccupantType.lotOccupantTypeId.toString()}" />
|
||||||
|
<button class="button is-success" type="submit" aria-label="Save">
|
||||||
|
<i class="fas fa-save" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</td><td class="is-nowrap">
|
||||||
|
<div class="field is-grouped">
|
||||||
|
<div class="control">
|
||||||
|
${los.getMoveUpDownButtonFieldHTML('button--moveLotOccupantTypeUp', 'button--moveLotOccupantTypeDown', false)}
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-danger is-light button--deleteLotOccupantType"
|
||||||
|
data-tooltip="Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type"
|
||||||
|
type="button"
|
||||||
|
aria-label="Delete ${los.escapedAliases.Lot} ${los.escapedAliases.Occupant} Type">
|
||||||
|
<i class="fas fa-trash" aria-hidden="true"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>`;
|
||||||
|
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();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
|
@ -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:"")})();
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
|
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
|
||||||
/* eslint-disable unicorn/prefer-module */
|
/* eslint-disable unicorn/prefer-module */
|
||||||
|
|
||||||
import type { LOS } from '../types/globalTypes.js'
|
import type { LOS } from '../../types/globalTypes.js'
|
||||||
|
|
||||||
declare const exports: Record<string, unknown>
|
declare const exports: Record<string, unknown>
|
||||||
;(() => {
|
;(() => {
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -4,8 +4,8 @@
|
||||||
import type { BulmaJS } from '@cityssm/bulma-js/types.js'
|
import type { BulmaJS } from '@cityssm/bulma-js/types.js'
|
||||||
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/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 { LotComment, LotTypeField } from '../types/recordTypes.js'
|
import type { LotComment, LotTypeField } from '../../types/recordTypes.js'
|
||||||
|
|
||||||
declare const cityssm: cityssmGlobal
|
declare const cityssm: cityssmGlobal
|
||||||
declare const bulmaJS: BulmaJS
|
declare const bulmaJS: BulmaJS
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/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 { LotOccupancy } from '../types/recordTypes.js'
|
import type { LotOccupancy } from '../../types/recordTypes.js'
|
||||||
|
|
||||||
declare const cityssm: cityssmGlobal
|
declare const cityssm: cityssmGlobal
|
||||||
|
|
||||||
|
|
@ -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=`<div class="message is-info">\n <p class="message-body">There are no ${e.escapedAliases.lots} that meet the search criteria.</p>\n </div>`);const m=document.createElement("tbody");for(const t of h.lots)m.insertAdjacentHTML("beforeend",`<tr>\n <td>\n <a class="has-text-weight-bold" href="${e.getLotURL(t.lotId)}">\n ${cityssm.escapeHTML(null!==(n=t.lotName)&&void 0!==n?n:"")}\n </a>\n </td><td>\n <a href="${e.getMapURL(t.mapId)}">\n ${t.mapName?cityssm.escapeHTML(t.mapName):'<span class="has-text-grey">(No Name)</span>'}\n </a>\n </td><td>\n ${cityssm.escapeHTML(null!==(r=t.lotType)&&void 0!==r?r:"")}\n </td><td>\n ${t.lotStatusId?cityssm.escapeHTML(null!==(o=t.lotStatus)&&void 0!==o?o:""):'<span class="has-text-grey">(No Status)</span>'}<br />\n ${(null!==(l=t.lotOccupancyCount)&&void 0!==l?l:0)>0?'<span class="is-size-7">Currently Occupied</span>':""}\n </td>\n </tr>`);s.innerHTML=`<table class="table is-fullwidth is-striped is-hoverable has-sticky-header">\n <thead><tr>\n <th>${e.escapedAliases.Lot}</th>\n <th>${e.escapedAliases.Map}</th>\n <th>${e.escapedAliases.Lot} Type</th>\n <th>Status</th>\n </tr></thead>\n <table>`,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()})();
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/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 { Lot } from '../types/recordTypes.js'
|
import type { Lot } from '../../types/recordTypes.js'
|
||||||
|
|
||||||
declare const cityssm: cityssmGlobal
|
declare const cityssm: cityssmGlobal
|
||||||
|
|
||||||
|
|
@ -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")})();
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
|
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
|
||||||
/* eslint-disable unicorn/prefer-module */
|
/* eslint-disable unicorn/prefer-module */
|
||||||
|
|
||||||
import type { LOS } from '../types/globalTypes.js'
|
import type { LOS } from '../../types/globalTypes.js'
|
||||||
|
|
||||||
declare const exports: Record<string, unknown>
|
declare const exports: Record<string, unknown>
|
||||||
;(() => {
|
;(() => {
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -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 { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/types.js'
|
||||||
import type { Options as BulmaCalendarOptions } from 'bulma-calendar'
|
import type { Options as BulmaCalendarOptions } from 'bulma-calendar'
|
||||||
|
|
||||||
import type { LOS } from '../types/globalTypes.js'
|
import type { LOS } from '../../types/globalTypes.js'
|
||||||
|
|
||||||
type RandomColorHue =
|
type RandomColorHue =
|
||||||
| 'red'
|
| 'red'
|
||||||
|
|
@ -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"})})}}})})})();
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
import type { BulmaJS } from '@cityssm/bulma-js/types.js'
|
import type { BulmaJS } from '@cityssm/bulma-js/types.js'
|
||||||
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/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 cityssm: cityssmGlobal
|
||||||
declare const bulmaJS: BulmaJS
|
declare const bulmaJS: BulmaJS
|
||||||
|
|
@ -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",`<tr>\n <td>\n <a class="has-text-weight-bold" href="${a.getMapURL(t.mapId)}">\n ${cityssm.escapeHTML(""===(null!==(r=t.mapName)&&void 0!==r?r:"")?"(No Name)":null!==(o=t.mapName)&&void 0!==o?o:"")}\n </a><br />\n <span class="is-size-7">\n ${cityssm.escapeHTML(null!==(c=t.mapDescription)&&void 0!==c?c:"")}\n </span>\n </td><td>\n ${""===(null!==(p=t.mapAddress1)&&void 0!==p?p:"")?"":`${cityssm.escapeHTML(null!==(m=t.mapAddress1)&&void 0!==m?m:"")}<br />`}\n ${""===(null!==(u=t.mapAddress2)&&void 0!==u?u:"")?"":`${cityssm.escapeHTML(null!==(h=t.mapAddress2)&&void 0!==h?h:"")}<br />`}\n ${t.mapCity||t.mapProvince?`${cityssm.escapeHTML(null!==(v=t.mapCity)&&void 0!==v?v:"")}, ${cityssm.escapeHTML(null!==($=t.mapProvince)&&void 0!==$?$:"")}<br />`:""}\n ${""===(null!==(L=t.mapPostalCode)&&void 0!==L?L:"")?"":cityssm.escapeHTML(null!==(f=t.mapPostalCode)&&void 0!==f?f:"")}\n </td><td>\n ${cityssm.escapeHTML(null!==(b=t.mapPhoneNumber)&&void 0!==b?b:"")}\n </td><td class="has-text-centered">\n ${t.mapLatitude&&t.mapLongitude?'<span data-tooltip="Has Geographic Coordinates">\n <i class="fas fa-map-marker-alt" aria-label="Has Geographic Coordinates"></i>\n </span>':""}\n </td><td class="has-text-centered">\n ${""===(null!==(y=t.mapSVG)&&void 0!==y?y:"")?"":'<span data-tooltip="Has Image"><i class="fas fa-image" aria-label="Has Image"></i></span>'}\n </td><td class="has-text-right">\n <a href="${a.urlPrefix}/lots?mapId=${t.mapId}">${t.lotCount}</a>\n </td>\n </tr>`))}if(n.innerHTML="",0===H)n.innerHTML=`<div class="message is-info">\n <p class="message-body">There are no ${a.escapedAliases.maps} that meet the search criteria.</p>\n </div>`;else{const e=document.createElement("table");e.className="table is-fullwidth is-striped is-hoverable has-sticky-header",e.innerHTML=`<thead><tr>\n <th>${a.escapedAliases.Map}</th>\n <th>Address</th>\n <th>Phone Number</th>\n <th class="has-text-centered">Coordinates</th>\n <th class="has-text-centered">Image</th>\n <th class="has-text-right">${a.escapedAliases.Lot} Count</th>\n </tr></thead>`,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()})();
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
import type { cityssmGlobal } from '@cityssm/bulma-webapp-js/src/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 { MapRecord } from '../types/recordTypes.js'
|
import type { MapRecord } from '../../types/recordTypes.js'
|
||||||
|
|
||||||
declare const cityssm: cityssmGlobal
|
declare const cityssm: cityssmGlobal
|
||||||
|
|
||||||
|
|
@ -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)}})();
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue