diff --git a/package-lock.json b/package-lock.json
index 3ef1029..8cfda28 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"dependencies": {
"@f0rce/ace-widget": "1.0.2",
"@polymer/polymer": "3.5.1",
+ "@vaadin-component-factory/vcf-pdf-viewer": "2.0.1",
"@vaadin/bundles": "24.4.2",
"@vaadin/common-frontend": "0.0.19",
"@vaadin/polymer-legacy-adapter": "24.4.2",
@@ -23,6 +24,7 @@
"construct-style-sheets-polyfill": "3.1.0",
"date-fns": "2.29.3",
"lit": "3.1.4",
+ "print-js": "1.6.0",
"proj4": "2.11.0",
"react": "18.3.1",
"react-dom": "18.3.1",
@@ -83,7 +85,6 @@
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
"integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
- "dev": true,
"dependencies": {
"@babel/highlight": "^7.24.7",
"picocolors": "^1.0.0"
@@ -431,7 +432,6 @@
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
"integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
- "dev": true,
"engines": {
"node": ">=6.9.0"
}
@@ -477,7 +477,6 @@
"version": "7.24.7",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
"integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
- "dev": true,
"dependencies": {
"@babel/helper-validator-identifier": "^7.24.7",
"chalk": "^2.4.2",
@@ -2832,6 +2831,22 @@
"@babel/types": "^7.20.7"
}
},
+ "node_modules/@types/buble": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmjs.org/@types/buble/-/buble-0.19.2.tgz",
+ "integrity": "sha512-uUD8zIfXMKThmFkahTXDGI3CthFH1kMg2dOm3KLi4GlC5cbARA64bEcUMbbWdWdE73eoc/iBB9PiTMqH0dNS2Q==",
+ "dependencies": {
+ "magic-string": "^0.25.0"
+ }
+ },
+ "node_modules/@types/buble/node_modules/magic-string": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
+ "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+ "dependencies": {
+ "sourcemap-codec": "^1.4.8"
+ }
+ },
"node_modules/@types/estree": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
@@ -2888,6 +2903,27 @@
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="
},
+ "node_modules/@vaadin-component-factory/vcf-pdf-viewer": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@vaadin-component-factory/vcf-pdf-viewer/-/vcf-pdf-viewer-2.0.1.tgz",
+ "integrity": "sha512-ZGvtaapYZGbSTq5dxgxmXP5LXXGmKJ54ynSiqDBlMtVmyY/qe98mA8EbIDqeOHFR6j+Ir/CjBV/Q1hRgebb5SQ==",
+ "dependencies": {
+ "@polymer/polymer": "^3.4.1",
+ "@vaadin/button": "^24.1.1",
+ "@vaadin/component-base": "^24.1.1",
+ "@vaadin/icon": "^24.1.1",
+ "@vaadin/item": "^24.1.1",
+ "@vaadin/list-box": "^24.1.1",
+ "@vaadin/select": "^24.1.1",
+ "@vaadin/text-field": "^24.1.1",
+ "@vaadin/vaadin-lumo-styles": "^24.1.1",
+ "@vaadin/vaadin-material-styles": "^24.1.1",
+ "@vaadin/vaadin-themable-mixin": "^24.1.1",
+ "core-js": "^3.19.0",
+ "dommatrix": "^0.0.6",
+ "web-streams-polyfill": "^3.1.1"
+ }
+ },
"node_modules/@vaadin/a11y-base": {
"version": "24.4.2",
"resolved": "https://registry.npmjs.org/@vaadin/a11y-base/-/a11y-base-24.4.2.tgz",
@@ -4342,7 +4378,6 @@
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
- "dev": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -4350,6 +4385,14 @@
"node": ">=0.4.0"
}
},
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
"node_modules/acorn-node": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz",
@@ -4417,7 +4460,6 @@
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
"dependencies": {
"color-convert": "^1.9.0"
},
@@ -4633,11 +4675,137 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/buble": {
+ "version": "0.20.0",
+ "resolved": "https://registry.npmjs.org/buble/-/buble-0.20.0.tgz",
+ "integrity": "sha512-/1gnaMQE8xvd5qsNBl+iTuyjJ9XxeaVxAMF86dQ4EyxFJOZtsgOS8Ra+7WHgZTam5IFDtt4BguN0sH0tVTKrOw==",
+ "dependencies": {
+ "acorn": "^6.4.1",
+ "acorn-dynamic-import": "^4.0.0",
+ "acorn-jsx": "^5.2.0",
+ "chalk": "^2.4.2",
+ "magic-string": "^0.25.7",
+ "minimist": "^1.2.5",
+ "regexpu-core": "4.5.4"
+ },
+ "bin": {
+ "buble": "bin/buble"
+ }
+ },
+ "node_modules/buble/node_modules/acorn": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
+ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/buble/node_modules/acorn-dynamic-import": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz",
+ "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==",
+ "deprecated": "This is probably built in to whatever tool you're using. If you still need it... idk",
+ "peerDependencies": {
+ "acorn": "^6.0.0"
+ }
+ },
+ "node_modules/buble/node_modules/jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ }
+ },
+ "node_modules/buble/node_modules/magic-string": {
+ "version": "0.25.9",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
+ "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==",
+ "dependencies": {
+ "sourcemap-codec": "^1.4.8"
+ }
+ },
+ "node_modules/buble/node_modules/regenerate-unicode-properties": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz",
+ "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==",
+ "dependencies": {
+ "regenerate": "^1.4.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/buble/node_modules/regexpu-core": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz",
+ "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==",
+ "dependencies": {
+ "regenerate": "^1.4.0",
+ "regenerate-unicode-properties": "^8.0.2",
+ "regjsgen": "^0.5.0",
+ "regjsparser": "^0.6.0",
+ "unicode-match-property-ecmascript": "^1.0.4",
+ "unicode-match-property-value-ecmascript": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/buble/node_modules/regjsparser": {
+ "version": "0.6.9",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz",
+ "integrity": "sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==",
+ "dependencies": {
+ "jsesc": "~0.5.0"
+ },
+ "bin": {
+ "regjsparser": "bin/parser"
+ }
+ },
+ "node_modules/buble/node_modules/unicode-canonical-property-names-ecmascript": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
+ "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/buble/node_modules/unicode-match-property-ecmascript": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
+ "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
+ "dependencies": {
+ "unicode-canonical-property-names-ecmascript": "^1.0.4",
+ "unicode-property-aliases-ecmascript": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/buble/node_modules/unicode-match-property-value-ecmascript": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz",
+ "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/buble/node_modules/unicode-property-aliases-ecmascript": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz",
+ "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
"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
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
},
"node_modules/builtin-modules": {
"version": "3.3.0",
@@ -4735,7 +4903,6 @@
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
@@ -4878,7 +5045,6 @@
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
"dependencies": {
"color-name": "1.1.3"
}
@@ -4886,8 +5052,7 @@
"node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "dev": true
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
},
"node_modules/commander": {
"version": "8.3.0",
@@ -4929,6 +5094,16 @@
"resolved": "https://registry.npmjs.org/cookieconsent/-/cookieconsent-3.1.1.tgz",
"integrity": "sha512-v8JWLJcI7Zs9NWrs8hiVldVtm3EBF70TJI231vxn6YToBGj0c9dvdnYwltydkAnrbBMOM/qX1xLFrnTfm5wTag=="
},
+ "node_modules/core-js": {
+ "version": "3.38.1",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.38.1.tgz",
+ "integrity": "sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==",
+ "hasInstallScript": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/core-js"
+ }
+ },
"node_modules/core-js-compat": {
"version": "3.37.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz",
@@ -5153,6 +5328,137 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/dommatrix": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/dommatrix/-/dommatrix-0.0.6.tgz",
+ "integrity": "sha512-arWsB8xJsMDU/oSaz8W/ha8W65CJSNJGdFbIYJIuI3pUxT+wtb4vcr8OxNMU+R+Cz6Ad4j+BfwBjzC74AZkytQ==",
+ "dependencies": {
+ "@rollup/plugin-buble": "^0.21.3",
+ "@rollup/plugin-json": "^4.1.0",
+ "rollup-plugin-terser": "^5.3.0"
+ }
+ },
+ "node_modules/dommatrix/node_modules/@rollup/plugin-buble": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-buble/-/plugin-buble-0.21.3.tgz",
+ "integrity": "sha512-Iv8cCuFPnMdqV4pcyU+OrfjOfagPArRQ1PyQjx5KgHk3dARedI+8PNTLSMpJts0lQJr8yF2pAU4GxpxCBJ9HYw==",
+ "dependencies": {
+ "@rollup/pluginutils": "^3.0.8",
+ "@types/buble": "^0.19.2",
+ "buble": "^0.20.0"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0"
+ }
+ },
+ "node_modules/dommatrix/node_modules/@rollup/plugin-json": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz",
+ "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==",
+ "dependencies": {
+ "@rollup/pluginutils": "^3.0.8"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0 || ^2.0.0"
+ }
+ },
+ "node_modules/dommatrix/node_modules/@rollup/pluginutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
+ "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==",
+ "dependencies": {
+ "@types/estree": "0.0.39",
+ "estree-walker": "^1.0.1",
+ "picomatch": "^2.2.2"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ },
+ "peerDependencies": {
+ "rollup": "^1.20.0||^2.0.0"
+ }
+ },
+ "node_modules/dommatrix/node_modules/@types/estree": {
+ "version": "0.0.39",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz",
+ "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw=="
+ },
+ "node_modules/dommatrix/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=="
+ },
+ "node_modules/dommatrix/node_modules/estree-walker": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz",
+ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg=="
+ },
+ "node_modules/dommatrix/node_modules/rollup": {
+ "version": "2.79.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
+ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
+ "peer": true,
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/dommatrix/node_modules/rollup-plugin-terser": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-terser/-/rollup-plugin-terser-5.3.1.tgz",
+ "integrity": "sha512-1pkwkervMJQGFYvM9nscrUoncPwiKR/K+bHdjv6PFgRo3cgPHoRT83y2Aa3GvINj4539S15t/tpFPb775TDs6w==",
+ "deprecated": "This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser",
+ "dependencies": {
+ "@babel/code-frame": "^7.5.5",
+ "jest-worker": "^24.9.0",
+ "rollup-pluginutils": "^2.8.2",
+ "serialize-javascript": "^4.0.0",
+ "terser": "^4.6.2"
+ },
+ "peerDependencies": {
+ "rollup": ">=0.66.0 <3"
+ }
+ },
+ "node_modules/dommatrix/node_modules/serialize-javascript": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
+ "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "dependencies": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/dommatrix/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==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/dommatrix/node_modules/terser": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz",
+ "integrity": "sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==",
+ "dependencies": {
+ "commander": "^2.20.0",
+ "source-map": "~0.6.1",
+ "source-map-support": "~0.5.12"
+ },
+ "bin": {
+ "terser": "bin/terser"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -5372,7 +5678,6 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
"engines": {
"node": ">=0.8.0"
}
@@ -5526,7 +5831,6 @@
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
@@ -5772,7 +6076,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
"engines": {
"node": ">=4"
}
@@ -6478,6 +6781,29 @@
"node": ">=8"
}
},
+ "node_modules/jest-worker": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz",
+ "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==",
+ "dependencies": {
+ "merge-stream": "^2.0.0",
+ "supports-color": "^6.1.0"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -6754,6 +7080,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
+ },
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -7244,14 +7575,12 @@
"node_modules/picocolors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
- "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
- "dev": true
+ "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
"engines": {
"node": ">=8.6"
},
@@ -7317,6 +7646,11 @@
"node": ">= 0.8"
}
},
+ "node_modules/print-js": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/print-js/-/print-js-1.6.0.tgz",
+ "integrity": "sha512-BfnOIzSKbqGRtO4o0rnj/K3681BSd2QUrsIZy/+WdCIugjIswjmx3lDEZpXB2ruGf9d4b3YNINri81+J0FsBWg=="
+ },
"node_modules/proj4": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/proj4/-/proj4-2.11.0.tgz",
@@ -7386,7 +7720,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
- "dev": true,
"dependencies": {
"safe-buffer": "^5.1.0"
}
@@ -7582,8 +7915,7 @@
"node_modules/regenerate": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
- "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
- "dev": true
+ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A=="
},
"node_modules/regenerate-unicode-properties": {
"version": "10.1.1",
@@ -7647,6 +7979,11 @@
"node": ">=4"
}
},
+ "node_modules/regjsgen": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
+ "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A=="
+ },
"node_modules/regjsparser": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz",
@@ -7791,6 +8128,19 @@
}
}
},
+ "node_modules/rollup-pluginutils": {
+ "version": "2.8.2",
+ "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz",
+ "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==",
+ "dependencies": {
+ "estree-walker": "^0.6.1"
+ }
+ },
+ "node_modules/rollup-pluginutils/node_modules/estree-walker": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
+ "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w=="
+ },
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -7841,7 +8191,6 @@
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
- "dev": true,
"funding": [
{
"type": "github",
@@ -8039,7 +8388,6 @@
"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"
@@ -8049,7 +8397,6 @@
"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"
}
@@ -8058,8 +8405,7 @@
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
- "deprecated": "Please use @jridgewell/sourcemap-codec instead",
- "dev": true
+ "deprecated": "Please use @jridgewell/sourcemap-codec instead"
},
"node_modules/spdx-correct": {
"version": "3.2.0",
@@ -8337,7 +8683,6 @@
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
"dependencies": {
"has-flag": "^3.0.0"
},
@@ -9067,6 +9412,14 @@
"integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==",
"dev": true
},
+ "node_modules/web-streams-polyfill": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
+ "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/web-worker": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz",
diff --git a/package.json b/package.json
index f819db8..aae3eec 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,7 @@
"dependencies": {
"@f0rce/ace-widget": "1.0.2",
"@polymer/polymer": "3.5.1",
+ "@vaadin-component-factory/vcf-pdf-viewer": "2.0.1",
"@vaadin/bundles": "24.4.2",
"@vaadin/common-frontend": "0.0.19",
"@vaadin/polymer-legacy-adapter": "24.4.2",
@@ -19,6 +20,7 @@
"construct-style-sheets-polyfill": "3.1.0",
"date-fns": "2.29.3",
"lit": "3.1.4",
+ "print-js": "1.6.0",
"proj4": "2.11.0",
"react": "18.3.1",
"react-dom": "18.3.1",
@@ -48,6 +50,7 @@
"dependencies": {
"@f0rce/ace-widget": "1.0.2",
"@polymer/polymer": "3.5.1",
+ "@vaadin-component-factory/vcf-pdf-viewer": "2.0.1",
"@vaadin/bundles": "24.4.2",
"@vaadin/common-frontend": "0.0.19",
"@vaadin/polymer-legacy-adapter": "24.4.2",
@@ -62,6 +65,7 @@
"construct-style-sheets-polyfill": "3.1.0",
"date-fns": "2.29.3",
"lit": "3.1.4",
+ "print-js": "1.6.0",
"proj4": "2.11.0",
"react": "18.3.1",
"react-dom": "18.3.1",
@@ -87,7 +91,7 @@
"workbox-core": "7.1.0",
"workbox-precaching": "7.1.0"
},
- "hash": "ff8035f5a0dd319a5c705d9cea5b3e1d6c1a0bb871c35af8dd8e4ede5c65fe76"
+ "hash": "0962b593830d75a70657cde2e956e8c49b704d39c45bfd150cda9fdac99f1c6e"
},
"overrides": {
"@vaadin/bundles": "$@vaadin/bundles",
@@ -109,6 +113,8 @@
"@vaadin/vaadin-themable-mixin": "$@vaadin/vaadin-themable-mixin",
"@vaadin/vaadin-lumo-styles": "$@vaadin/vaadin-lumo-styles",
"@vaadin/vaadin-material-styles": "$@vaadin/vaadin-material-styles",
- "@f0rce/ace-widget": "$@f0rce/ace-widget"
+ "@f0rce/ace-widget": "$@f0rce/ace-widget",
+ "print-js": "$print-js",
+ "@vaadin-component-factory/vcf-pdf-viewer": "$@vaadin-component-factory/vcf-pdf-viewer"
}
}
diff --git a/pom.xml b/pom.xml
index 250c640..a9cae3e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -225,6 +225,21 @@
commons-lang3
3.14.0
+
+ org.vaadin.addons.componentfactory
+ vcf-pdf-viewer
+ 2.8.1
+
+
+ com.openhtmltopdf
+ openhtmltopdf-pdfbox
+ 1.0.10
+
+
+ org.freemarker
+ freemarker
+ 2.3.32
+
org.apache.maven.plugins
maven-surefire-plugin
diff --git a/src/main/bundles/dev.bundle b/src/main/bundles/dev.bundle
index 8bb97d2..98765af 100644
Binary files a/src/main/bundles/dev.bundle and b/src/main/bundles/dev.bundle differ
diff --git a/src/main/java/com/primefactorsolutions/service/ReportService.java b/src/main/java/com/primefactorsolutions/service/ReportService.java
new file mode 100644
index 0000000..0de93fd
--- /dev/null
+++ b/src/main/java/com/primefactorsolutions/service/ReportService.java
@@ -0,0 +1,72 @@
+package com.primefactorsolutions.service;
+
+import com.openhtmltopdf.pdfboxout.PdfBoxRenderer;
+import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
+import freemarker.template.Configuration;
+import freemarker.template.DefaultObjectWrapper;
+import freemarker.template.Template;
+import freemarker.template.TemplateExceptionHandler;
+import lombok.SneakyThrows;
+import org.apache.pdfbox.io.MemoryUsageSetting;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.jetbrains.annotations.NotNull;
+import org.springframework.stereotype.Service;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.util.TimeZone;
+
+@Service
+public class ReportService {
+
+ @SneakyThrows
+ public byte[] writeAsPdf(final String reportName, final Object model) {
+ try (var os = new ByteArrayOutputStream()) {
+ writeAsPdf(reportName, model, os);
+
+ return os.toByteArray();
+ }
+ }
+
+ @SneakyThrows
+ public void writeAsPdf(final String reportName, final Object model, final OutputStream out) {
+ var in = getTemplate(reportName);
+ final Configuration cfg = getConfiguration();
+ final Reader reader = new InputStreamReader(in);
+ final Template temp = new Template(reportName, reader, cfg);
+
+ var wrapper = new DefaultObjectWrapper(Configuration.VERSION_2_3_32);
+ ByteArrayOutputStream oo = new ByteArrayOutputStream();
+ Writer outTemplate = new OutputStreamWriter(oo);
+
+ temp.process(wrapper.wrap(model), outTemplate);
+
+ var builder = new PdfRendererBuilder();
+ builder.usePDDocument(new PDDocument(MemoryUsageSetting.setupMixed(1000000)));
+ builder.withHtmlContent(oo.toString(StandardCharsets.UTF_8), "/test");
+ builder.toStream(out);
+
+ try (PdfBoxRenderer pdfBoxRenderer = builder.buildPdfRenderer()) {
+ pdfBoxRenderer.layout();
+ pdfBoxRenderer.createPDF();
+ }
+ }
+
+ public static InputStream getTemplate(final String reportName) {
+ return ReportService.class.getResourceAsStream(String.format("/reports/%s.html", reportName));
+ }
+
+
+ @NotNull
+ private static Configuration getConfiguration() {
+ final Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
+ cfg.setDefaultEncoding("UTF-8");
+ cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
+ cfg.setLogTemplateExceptions(false);
+ cfg.setWrapUncheckedExceptions(true);
+ cfg.setFallbackOnNullLoopVariable(false);
+ cfg.setSQLDateAndTimeTimeZone(TimeZone.getDefault());
+
+ return cfg;
+ }
+}
diff --git a/src/main/java/com/primefactorsolutions/views/EmployeeView.java b/src/main/java/com/primefactorsolutions/views/EmployeeView.java
index 3f057dc..8303f8e 100644
--- a/src/main/java/com/primefactorsolutions/views/EmployeeView.java
+++ b/src/main/java/com/primefactorsolutions/views/EmployeeView.java
@@ -2,14 +2,20 @@ package com.primefactorsolutions.views;
import com.primefactorsolutions.model.Employee;
import com.primefactorsolutions.service.EmployeeService;
+import com.primefactorsolutions.service.ReportService;
+import com.vaadin.componentfactory.pdfviewer.PdfViewer;
+import com.vaadin.flow.component.ClickEvent;
import com.vaadin.flow.component.Component;
+import com.vaadin.flow.component.ComponentEventListener;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.combobox.ComboBox;
+import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.html.Image;
import com.vaadin.flow.component.notification.Notification;
+import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.EmailField;
@@ -18,12 +24,14 @@ import com.vaadin.flow.component.upload.Upload;
import com.vaadin.flow.component.upload.receivers.MemoryBuffer;
import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.router.*;
+import com.vaadin.flow.server.StreamResource;
import com.vaadin.flow.spring.annotation.SpringComponent;
import jakarta.annotation.security.PermitAll;
import org.springframework.context.annotation.Scope;
import org.vaadin.firitin.components.datepicker.VDatePicker;
import org.vaadin.firitin.form.BeanValidationForm;
+import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
@@ -36,102 +44,56 @@ import java.util.UUID;
@PageTitle("Employee")
@Route(value = "/employees/:employeeId?/:action?", layout = MainLayout.class)
public class EmployeeView extends BeanValidationForm implements HasUrlParameter {
- private final EmployeeService employeeService;
- // TODO: campo usado para registrar al empleado en LDAP. Este campo podria estar en otro form eventualmente.
- // INFORMACION PERSONAL
- private final TextField username = createTextField("Username: ", 30, true);
- private final TextField firstName = createTextField("Nombres: ", 30, true);
- private final TextField lastName = createTextField("Apellidos", 30, true);
- private final ComboBox status = createStatusComboBox();
- private final ComboBox gender = createGenderComboBox();
- private final VDatePicker birthday = new VDatePicker("Fecha de Nacimiento");
- private final TextField age = createTextField("Edad", 3, false);
- private final TextField birthCity = createTextField("Ciudad y País de Nacimiento", 20, false);
- private final TextField residenceAddress = createTextField("Dirección de Domicilio Actual", 50, false);
- private final TextField localAddress = createTextField("Dep/Provincia de Residencia", 10, false);
- private final ComboBox maritalStatus = createMaritalStatusComboBox();
- private final TextField numberOfChildren = createTextField("Numero de Hijos", 3, false);
- private final TextField ci = createTextField("CI", 30, false);
- private final TextField issuedIn = createTextField("Expedido en ", 30, false);
- private final TextField phoneNumber = createTextField("Teléfono", 8, false);
- private final EmailField personalEmail = createEmailField("E-mail");
- private final TextField cod = createTextField("Codigo de Empleado", 30, false);
- private final TextField position = createTextField("Cargo", 30, false);
- private final TextField team = createTextField("Equipo", 30, false);
- private final TextField leadManager = createTextField("Lead/Manager", 30, false);
- private final TextField project = createTextField("Proyecto", 30, false);
- private final TextField emergencyCName = createTextField("Nombres y Apellidos de Contacto", 50, false);
- private final TextField emergencyCAddress = createTextField("Dirección de Contacto", 50, false);
- private final TextField emergencyCPhone = createTextField("Teléfono de Contacto", 8, false);
- private final EmailField emergencyCEmail = createEmailField("Email de Contacto");
- private final MemoryBuffer buffer = new MemoryBuffer();
- private final Upload upload = new Upload(buffer);
- private final Image profileImagePreview = new Image();
-
- //INFORMACION PROFESIONAL
- private final TextField pTitle1 = createTextField("Título 1", 30, false);
- private final TextField pTitle2 = createTextField("Título 2", 30, false);
- private final TextField pTitle3 = createTextField("Título 3", 30, false);
- private final TextField pStudy1 = createTextField("Estudio 1", 30, false);
- private final TextField pStudy2 = createTextField("Estudio 2", 30, false);
- private final TextField pStudy3 = createTextField("Estudio 3", 30, false);
- private final TextField certification1 = createTextField("Certificación 1", 30, false);
- private final TextField certification2 = createTextField("Certificación 2", 30, false);
- private final TextField certification3 = createTextField("Certificación 3", 30, false);
- private final TextField certification4 = createTextField("Certificación 4", 30, false);
- private final TextField recognition = createTextField("Reconocimientos", 30, false);
- private final TextField achievements = createTextField("Logros Profesionales", 30, false);
- private final TextField language = createTextField("Idioma", 30, false);
- private final TextField languageLevel = createTextField("Nivel de Idioma", 30, false);
-
- //INFORMACION DE CONTRATACION
- private final VDatePicker dateOfEntry = new VDatePicker("Fecha de Ingreso");
- private final VDatePicker dateOfExit = new VDatePicker("Fecha de Retiro");
- private final TextField contractType = createTextField("Tipo de Contratación", 30, false);
- private final TextField seniority = createTextField("Antiguedad", 30, false);
- private final TextField salary = createTextField("Salario", 30, false);
- private final TextField bankName = createTextField("Banco", 30, false);
- private final TextField accountNumber = createTextField("Nro. de Cuenta", 30, false);
- private final TextField gpss = createTextField("Código Único de Asegurado (GPSS)", 30, false);
- private final TextField sss = createTextField("Matricula de Asegurado (SSS)", 30, false);
- private final TextField beneficiaries = createTextField("Derechohabientes", 30, false);
-
- //TITULOS PARA INFORMACION PERSONAL
- private final H2 infoPer = new H2("Información Personal");
- private final H3 infoGenr = new H3("Información General");
- private final H3 contEmerg = new H3("Contacto de Emergencia");
- //TITULOS PARA INFORMACIÓN PROFESIONAL
- private final H2 infProf = new H2("Información Profesional");
- private final H3 titulos = new H3("Titulos Profesionales y Estudios Realizados");
- private final H3 certif = new H3("Certificaciones Profesionales");
- private final H3 logros = new H3("Otros Logros y Reconocimientos");
- private final H3 idioma = new H3("Dominio de Idiomas");
- //TITULOS PARA INFORMACIÓN ADMINISTRATIVA
- private final H2 infoAdm = new H2("Información Administrativa");
- private final H3 infoCont = new H3("Información de Contratación");
- private final H3 datBanc = new H3("Datos Bancados");
- private final H3 datGest = new H3("Datos Gestora Pública y Seguro Social");
-
- //BOTONES
private static final String SAVE_BUTTON_TEXT = "Save";
private static final String EDIT_BUTTON_TEXT = "Edit";
- private final Button saveButton = new Button(SAVE_BUTTON_TEXT, e -> saveEmployee());
- private final Button editButton = new Button(EDIT_BUTTON_TEXT, e -> enableEditMode());
-
- //ALERTAS
private static final String NOTIFICATION_SAVE_SUCCESS = "Employee saved successfully.";
private static final String NOTIFICATION_VALIDATE_ERROR = "Please complete the required fields correctly.";
private static final String PHONE_NUMBER_ERROR_MESSAGE = "El teléfono debe contener solo números.";
+ private final EmployeeService employeeService;
+ private final ReportService reportService;
- public EmployeeView(final EmployeeService employeeService) {
+ // TODO: campo usado para registrar al empleado en LDAP. Este campo podria estar en otro form eventualmente.
+ private final TextField username = createTextField("Username: ", 30, true);
+ private final TextField firstName = createTextField("Nombres: ", 30, true);
+ private final TextField lastName = createTextField("Apellidos", 30, true);
+ private final ComboBox status = createStatusComboBox();
+ private final VDatePicker birthday = new VDatePicker("Fecha de Nacimiento");
+ private final TextField birthCity = createTextField("Ciudad y País de Nacimiento", 20, false);
+ private final ComboBox maritalStatus = createMaritalStatusComboBox();
+ private final TextField residenceAddress = createTextField("Dirección de Residencia", 50, false);
+ private final TextField phoneNumber = createTextField("Teléfono", 8, false);
+ private final EmailField personalEmail = createEmailField("E-mail");
+ private final TextField position = createTextField("Cargo", 30, false);
+ private final TextField team = createTextField("Equipo", 30, false);
+ private final TextField emergencyCName = createTextField("Nombres y Apellidos de Contacto", 50, false);
+ private final TextField emergencyCAddress = createTextField("Dirección de Contacto", 50, false);
+ private final TextField emergencyCPhone = createTextField("Teléfono de Contacto", 8, false);
+ private final EmailField emergencyCEmail = createEmailField("Email de Contacto");
+
+ private final MemoryBuffer buffer = new MemoryBuffer();
+ private final Upload upload = new Upload(buffer);
+ private final Image profileImagePreview = new Image();
+
+ private final Button saveButton = new Button(SAVE_BUTTON_TEXT, e -> saveEmployee());
+ private final Button editButton = new Button(EDIT_BUTTON_TEXT, e -> enableEditMode());
+ private final Button reportButton = new Button("Ficha");
+ private final Dialog dialog = new Dialog();
+ private final PdfViewer pdfViewer = new PdfViewer();
+ private final H2 mt = new H2("Información General del Empleado");
+ private final H3 fs = new H3("Información Personal");
+ private final H3 ss = new H3("Datos de Contacto de Emergencia");
+ private final H3 si = new H3("Foto del Empleado");
+
+ public EmployeeView(final EmployeeService employeeService, final ReportService reportService) {
super(Employee.class);
this.employeeService = employeeService;
+ this.reportService = reportService;
saveButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
configureComponents();
- assembleLayout();
+ addClassName("main-layout");
}
private void configureComponents() {
@@ -142,18 +104,17 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
configureUpload();
saveButton.setVisible(true);
editButton.setVisible(true);
+ reportButton.setVisible(true);
- birthday.addValueChangeListener(event -> calculateAge());
+ reportButton.addClickListener((ComponentEventListener>) buttonClickEvent -> {
+ var employee = getEntity();
+ byte[] pdfContent = reportService.writeAsPdf("ficha", employee);
+ var resource = new StreamResource("ficha.pdf", () -> new ByteArrayInputStream(pdfContent));
+ pdfViewer.setSrc(resource);
+ dialog.open();
+ });
- }
-
- private void calculateAge() {
- if (birthday.getValue() != null) {
- int currentYear = java.time.LocalDate.now().getYear();
- int birthYear = birthday.getValue().getYear();
- int ages = currentYear - birthYear;
- age.setValue(String.valueOf(ages));
- }
+ initDialog();
}
private void configureUpload() {
@@ -182,67 +143,27 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
}
}
- private void assembleLayout() {
- HorizontalLayout mainLayout = new HorizontalLayout();
- VerticalLayout contentLayout1 = createContentLayout();
- VerticalLayout contentLayout2 = createContentLayout();
- VerticalLayout contentLayout3 = createContentLayout();
+ private void initDialog() {
+ pdfViewer.setSizeFull();
+ H2 headline = new H2("Ficha Empleado");
+ headline.getStyle().set("margin", "var(--lumo-space-m) 0 0 0")
+ .set("font-size", "1.5em").set("font-weight", "bold");
- contentLayout1.add(
- infoPer,
- infoGenr,
- upload, profileImagePreview,
- firstName, lastName,
- gender, status,
- birthday, age,
- birthCity, residenceAddress, localAddress,
- maritalStatus, ci, issuedIn, numberOfChildren,
- phoneNumber, personalEmail,
- cod, position, team, leadManager, project,
- contEmerg,
- emergencyCName, emergencyCAddress, emergencyCPhone, emergencyCEmail);
- contentLayout2.add(
- infProf,
- titulos,
- pTitle1, pTitle2, pTitle3,
- pStudy1, pStudy2, pStudy3,
- certif,
- certification1, certification2, certification3, certification4,
- logros,
- recognition, achievements,
- idioma,
- language, languageLevel
- );
- contentLayout3.add(
- infoAdm,
- infoCont,
- dateOfEntry, dateOfExit,
- contractType, seniority, salary,
- datBanc,
- bankName, accountNumber,
- datGest,
- gpss, sss, beneficiaries
- );
+ final Button cancelDialogButton = new Button("Close", e -> dialog.close());
+ final HorizontalLayout buttonLayout = new HorizontalLayout(cancelDialogButton);
+ buttonLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.END);
- mainLayout.add(contentLayout1, infProf,
- titulos,
- pTitle1, pTitle2, pTitle3,
- pStudy1, pStudy2, pStudy3,
- certif,
- certification1, certification2, certification3, certification4,
- logros,
- recognition, achievements,
- idioma,
- language, languageLevel,
- infoAdm,
- infoCont,
- dateOfEntry, dateOfExit,
- contractType, seniority, salary,
- datBanc,
- bankName, accountNumber,
- datGest,
- gpss, sss, beneficiaries, saveButton, editButton);
- addClassName("main-layout");
+ final VerticalLayout dialogLayout = new VerticalLayout(headline, pdfViewer, buttonLayout);
+ dialogLayout.getStyle().set("height", "100%");
+ dialogLayout.getStyle().set("overflow", "hidden");
+ dialogLayout.getStyle().set("display", "flex");
+ dialogLayout.getStyle().set("flex-direction", "column");
+ dialogLayout.setPadding(false);
+ dialogLayout.setAlignItems(FlexComponent.Alignment.STRETCH);
+ dialogLayout.getStyle().set("width", "700px").set("max-width", "100%");
+ dialogLayout.getStyle().set("height", "800px").set("max-height", "100%");
+
+ dialog.add(dialogLayout);
}
private ComboBox createMaritalStatusComboBox() {
@@ -256,15 +177,7 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
ComboBox comboBox = new ComboBox<>("Estado");
comboBox.setItems(Employee.Status.values());
comboBox.setItemLabelGenerator(Employee.Status::name);
- comboBox.setRequiredIndicatorVisible(true);
- return comboBox;
- }
-
- private ComboBox createGenderComboBox() {
- ComboBox comboBox = new ComboBox<>("Genero");
- comboBox.setItems(Employee.Gender.values());
- comboBox.setItemLabelGenerator(Employee.Gender::name);
- comboBox.setRequiredIndicatorVisible(true);
+ comboBox.setRequiredIndicatorVisible(true); // Indicador de campo requerido
return comboBox;
}
@@ -382,38 +295,6 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
emergencyCEmail.setReadOnly(true);
upload.setVisible(true);
profileImagePreview.setVisible(true);
- age.setReadOnly(true);
- gender.setReadOnly(true);
- status.setReadOnly(true);
- ci.setReadOnly(true);
- issuedIn.setReadOnly(true);
- pTitle1.setReadOnly(true);
- pTitle2.setReadOnly(true);
- pTitle3.setReadOnly(true);
- pStudy1.setReadOnly(true);
- pStudy2.setReadOnly(true);
- pStudy3.setReadOnly(true);
- certification1.setReadOnly(true);
- certification2.setReadOnly(true);
- certification3.setReadOnly(true);
- certification4.setReadOnly(true);
- recognition.setReadOnly(true);
- achievements.setReadOnly(true);
- language.setReadOnly(true);
- languageLevel.setReadOnly(true);
- cod.setReadOnly(true);
- leadManager.setReadOnly(true);
- project.setReadOnly(true);
- dateOfEntry.setReadOnly(true);
- dateOfExit.setReadOnly(true);
- contractType.setReadOnly(true);
- seniority.setReadOnly(true);
- salary.setReadOnly(true);
- bankName.setReadOnly(true);
- accountNumber.setReadOnly(true);
- gpss.setReadOnly(true);
- sss.setReadOnly(true);
- beneficiaries.setReadOnly(true);
}
private void setFieldsEditable() {
@@ -433,65 +314,15 @@ public class EmployeeView extends BeanValidationForm implements HasUrl
emergencyCPhone.setReadOnly(false);
emergencyCEmail.setReadOnly(false);
upload.setVisible(true);
- age.setReadOnly(false);
- gender.setReadOnly(false);
- status.setReadOnly(false);
- ci.setReadOnly(false);
- issuedIn.setReadOnly(false);
- pTitle1.setReadOnly(false);
- pTitle2.setReadOnly(false);
- pTitle3.setReadOnly(false);
- pStudy1.setReadOnly(false);
- pStudy2.setReadOnly(false);
- pStudy3.setReadOnly(false);
- certification1.setReadOnly(false);
- certification2.setReadOnly(false);
- certification3.setReadOnly(false);
- certification4.setReadOnly(false);
- recognition.setReadOnly(false);
- achievements.setReadOnly(false);
- language.setReadOnly(false);
- languageLevel.setReadOnly(false);
- cod.setReadOnly(false);
- leadManager.setReadOnly(false);
- project.setReadOnly(false);
- dateOfEntry.setReadOnly(false);
- dateOfExit.setReadOnly(false);
- contractType.setReadOnly(false);
- seniority.setReadOnly(false);
- salary.setReadOnly(false);
- bankName.setReadOnly(false);
- accountNumber.setReadOnly(false);
- gpss.setReadOnly(false);
- sss.setReadOnly(false);
- beneficiaries.setReadOnly(false);
}
@Override
protected List getFormComponents() {
return List.of(
- username,
- infoPer,
- infoGenr,
- upload, profileImagePreview,
- firstName, lastName,
- gender, status,
- birthday, age,
- birthCity, residenceAddress, localAddress,
- maritalStatus, ci, issuedIn, numberOfChildren,
- phoneNumber, personalEmail,
- cod, position, team, leadManager, project,
- contEmerg, emergencyCName, emergencyCAddress, emergencyCPhone, emergencyCEmail,
- infProf,
- titulos, pTitle1, pTitle2, pTitle3, pStudy1, pStudy2, pStudy3,
- certif, certification1, certification2, certification3, certification4,
- logros, recognition, achievements,
- idioma, language, languageLevel,
- infoAdm,
- infoCont, dateOfEntry, dateOfExit, contractType, seniority, salary,
- datBanc, bankName, accountNumber,
- datGest, gpss, sss, beneficiaries,
- saveButton, editButton
+ mt, fs, username, firstName, lastName, status, birthday, birthCity, maritalStatus,
+ residenceAddress, phoneNumber, personalEmail, position, team, ss, emergencyCName,
+ emergencyCAddress, emergencyCPhone, emergencyCEmail, si, upload, profileImagePreview,
+ saveButton, editButton, reportButton, dialog
);
}
}
diff --git a/src/main/resources/reports/ficha.html b/src/main/resources/reports/ficha.html
new file mode 100644
index 0000000..6e84b3c
--- /dev/null
+++ b/src/main/resources/reports/ficha.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+Empleado
+
+
+ - Nombre
+ - ${firstName!""}
+ - Telefono
+ - ${phoneNumber!""}
+
+
+
+
+
+
+
+