feat: signature (#194)
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 8s

* refactor: enable profile signature option in ProfileMenu

* feat: add signature api function

* refactor: add new translation keys for 'Draw' and 'New Upload' in English and Thai

* refactor: update image URL variable and improve translation keys in CanvasComponent and MainLayout

* refactor: get function

* feat: add delete signature function

* feat: add canvas manipulation functions and integrate signature submission in MainLayout (unfinished)

* chore(deps): update

---------

Co-authored-by: puriphatt <puriphat@frappet.com>
Co-authored-by: Methapon2001 <61303214+Methapon2001@users.noreply.github.com>
This commit is contained in:
Methapon Metanipat 2025-03-27 09:01:42 +07:00 committed by GitHub
parent 3646956038
commit 0e685a99f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 378 additions and 149 deletions

View file

@ -16,7 +16,7 @@
}, },
"dependencies": { "dependencies": {
"@peaceroad/markdown-it-figure-with-p-caption": "^0.11.0", "@peaceroad/markdown-it-figure-with-p-caption": "^0.11.0",
"@quasar/extras": "^1.16.4", "@quasar/extras": "^1.16.17",
"@tato30/vue-pdf": "^1.11.0", "@tato30/vue-pdf": "^1.11.0",
"@vuepic/vue-datepicker": "^8.8.1", "@vuepic/vue-datepicker": "^8.8.1",
"apexcharts": "^4.5.0", "apexcharts": "^4.5.0",
@ -36,7 +36,7 @@
"number-to-words": "^1.2.4", "number-to-words": "^1.2.4",
"open-props": "^1.7.5", "open-props": "^1.7.5",
"pinia": "^2.2.2", "pinia": "^2.2.2",
"quasar": "^2.16.0", "quasar": "^2.18.1",
"signature_pad": "^5.0.2", "signature_pad": "^5.0.2",
"socket.io-client": "^4.7.5", "socket.io-client": "^4.7.5",
"tesseract.js": "^5.1.1", "tesseract.js": "^5.1.1",
@ -49,14 +49,14 @@
"vue-pdf": "^4.3.0", "vue-pdf": "^4.3.0",
"vue-router": "^4.4.3", "vue-router": "^4.4.3",
"vue-tsc": "^2.2.8", "vue-tsc": "^2.2.8",
"vue3-apexcharts": "^1.7.0" "vue3-apexcharts": "^1.8.0"
}, },
"devDependencies": { "devDependencies": {
"@faker-js/faker": "^9.3.0", "@faker-js/faker": "^9.3.0",
"@iconify/vue": "^4.1.2", "@iconify/vue": "^4.1.2",
"@intlify/unplugin-vue-i18n": "^6.0.5", "@intlify/unplugin-vue-i18n": "^6.0.5",
"@playwright/test": "^1.46.1", "@playwright/test": "^1.46.1",
"@quasar/app-vite": "^2.1.0", "@quasar/app-vite": "^2.2.0",
"@types/markdown-it": "^14.1.2", "@types/markdown-it": "^14.1.2",
"@types/markdown-it-highlightjs": "^3.3.4", "@types/markdown-it-highlightjs": "^3.3.4",
"@types/node": "^20.16.1", "@types/node": "^20.16.1",

330
pnpm-lock.yaml generated
View file

@ -12,7 +12,7 @@ importers:
specifier: ^0.11.0 specifier: ^0.11.0
version: 0.11.0 version: 0.11.0
'@quasar/extras': '@quasar/extras':
specifier: ^1.16.4 specifier: ^1.16.17
version: 1.16.17 version: 1.16.17
'@tato30/vue-pdf': '@tato30/vue-pdf':
specifier: ^1.11.0 specifier: ^1.11.0
@ -72,7 +72,7 @@ importers:
specifier: ^2.2.2 specifier: ^2.2.2
version: 2.2.2(typescript@5.5.4)(vue@3.4.38(typescript@5.5.4)) version: 2.2.2(typescript@5.5.4)(vue@3.4.38(typescript@5.5.4))
quasar: quasar:
specifier: ^2.16.0 specifier: ^2.18.1
version: 2.18.1 version: 2.18.1
signature_pad: signature_pad:
specifier: ^5.0.2 specifier: ^5.0.2
@ -111,7 +111,7 @@ importers:
specifier: ^2.2.8 specifier: ^2.2.8
version: 2.2.8(typescript@5.5.4) version: 2.2.8(typescript@5.5.4)
vue3-apexcharts: vue3-apexcharts:
specifier: ^1.7.0 specifier: ^1.8.0
version: 1.8.0(apexcharts@4.5.0)(vue@3.4.38(typescript@5.5.4)) version: 1.8.0(apexcharts@4.5.0)(vue@3.4.38(typescript@5.5.4))
devDependencies: devDependencies:
'@faker-js/faker': '@faker-js/faker':
@ -127,7 +127,7 @@ importers:
specifier: ^1.46.1 specifier: ^1.46.1
version: 1.46.1 version: 1.46.1
'@quasar/app-vite': '@quasar/app-vite':
specifier: ^2.1.0 specifier: ^2.2.0
version: 2.2.0(@types/node@20.16.1)(eslint@9.23.0)(pinia@2.2.2(typescript@5.5.4)(vue@3.4.38(typescript@5.5.4)))(quasar@2.18.1)(rollup@4.37.0)(sass@1.77.8)(terser@5.31.0)(typescript@5.5.4)(vue-router@4.4.3(vue@3.4.38(typescript@5.5.4)))(vue@3.4.38(typescript@5.5.4)) version: 2.2.0(@types/node@20.16.1)(eslint@9.23.0)(pinia@2.2.2(typescript@5.5.4)(vue@3.4.38(typescript@5.5.4)))(quasar@2.18.1)(rollup@4.37.0)(sass@1.77.8)(terser@5.31.0)(typescript@5.5.4)(vue-router@4.4.3(vue@3.4.38(typescript@5.5.4)))(vue@3.4.38(typescript@5.5.4))
'@types/markdown-it': '@types/markdown-it':
specifier: ^14.1.2 specifier: ^14.1.2
@ -739,6 +739,9 @@ packages:
'@types/estree@1.0.6': '@types/estree@1.0.6':
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
'@types/estree@1.0.7':
resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==}
'@types/express-serve-static-core@4.19.0': '@types/express-serve-static-core@4.19.0':
resolution: {integrity: sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==} resolution: {integrity: sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==}
@ -1149,8 +1152,8 @@ packages:
bmp-js@0.1.0: bmp-js@0.1.0:
resolution: {integrity: sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==} resolution: {integrity: sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==}
bn.js@4.12.0: bn.js@4.12.1:
resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} resolution: {integrity: sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==}
bn.js@5.2.1: bn.js@5.2.1:
resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==}
@ -1185,8 +1188,9 @@ packages:
browserify-des@1.0.2: browserify-des@1.0.2:
resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==}
browserify-rsa@4.1.0: browserify-rsa@4.1.1:
resolution: {integrity: sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==} resolution: {integrity: sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==}
engines: {node: '>= 0.10'}
browserify-sign@4.2.3: browserify-sign@4.2.3:
resolution: {integrity: sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==} resolution: {integrity: sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==}
@ -1240,10 +1244,22 @@ packages:
resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
call-bind-apply-helpers@1.0.2:
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
engines: {node: '>= 0.4'}
call-bind@1.0.7: call-bind@1.0.7:
resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
call-bind@1.0.8:
resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==}
engines: {node: '>= 0.4'}
call-bound@1.0.4:
resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
engines: {node: '>= 0.4'}
callsites@3.1.0: callsites@3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -1251,8 +1267,8 @@ packages:
camel-case@4.1.2: camel-case@4.1.2:
resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==}
caniuse-lite@1.0.30001651: caniuse-lite@1.0.30001707:
resolution: {integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==} resolution: {integrity: sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==}
canvas@2.11.2: canvas@2.11.2:
resolution: {integrity: sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==} resolution: {integrity: sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==}
@ -1287,8 +1303,9 @@ packages:
resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==}
engines: {node: '>=8'} engines: {node: '>=8'}
cipher-base@1.0.4: cipher-base@1.0.6:
resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} resolution: {integrity: sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==}
engines: {node: '>= 0.10'}
class-utils@0.3.6: class-utils@0.3.6:
resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==}
@ -1439,8 +1456,9 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
crypto-browserify@3.12.0: crypto-browserify@3.12.1:
resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} resolution: {integrity: sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==}
engines: {node: '>= 0.10'}
csstype@3.1.3: csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
@ -1471,6 +1489,15 @@ packages:
supports-color: supports-color:
optional: true optional: true
debug@4.4.0:
resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
decode-uri-component@0.2.2: decode-uri-component@0.2.2:
resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==}
engines: {node: '>=0.10'} engines: {node: '>=0.10'}
@ -1565,6 +1592,10 @@ packages:
resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
engines: {node: '>=12'} engines: {node: '>=12'}
dunder-proto@1.0.1:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
duplexify@3.7.1: duplexify@3.7.1:
resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==}
@ -1581,8 +1612,8 @@ packages:
resolution: {integrity: sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==} resolution: {integrity: sha512-wkgGT6kugeQk/P6VZ/f4T+4HB41BVgNBq5CDIZVbQ02nvTVqAiVTbskxxu3eA/X96lMlfYOwnLQpN2v5E1zDEg==}
engines: {node: '>= 0.4.0'} engines: {node: '>= 0.4.0'}
elliptic@6.5.7: elliptic@6.6.1:
resolution: {integrity: sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==} resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==}
emoji-regex@8.0.0: emoji-regex@8.0.0:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
@ -1634,10 +1665,18 @@ packages:
resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
es-define-property@1.0.1:
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
engines: {node: '>= 0.4'}
es-errors@1.3.0: es-errors@1.3.0:
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
es-object-atoms@1.1.1:
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
engines: {node: '>= 0.4'}
esbuild@0.25.1: esbuild@0.25.1:
resolution: {integrity: sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==} resolution: {integrity: sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
@ -1922,6 +1961,14 @@ packages:
resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
get-intrinsic@1.3.0:
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
engines: {node: '>= 0.4'}
get-proto@1.0.1:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'}
get-value@2.0.6: get-value@2.0.6:
resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
@ -1951,6 +1998,10 @@ packages:
gopd@1.0.1: gopd@1.0.1:
resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
graceful-fs@4.2.11: graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
@ -1969,6 +2020,10 @@ packages:
resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
has-symbols@1.1.0:
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
engines: {node: '>= 0.4'}
has-unicode@2.0.1: has-unicode@2.0.1:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
@ -1988,13 +2043,9 @@ packages:
resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
hash-base@3.0.4: hash-base@3.0.5:
resolution: {integrity: sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==} resolution: {integrity: sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==}
engines: {node: '>=4'} engines: {node: '>= 0.10'}
hash-base@3.1.0:
resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==}
engines: {node: '>=4'}
hash.js@1.1.7: hash.js@1.1.7:
resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==}
@ -2050,8 +2101,8 @@ packages:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'} engines: {node: '>= 4'}
immutable@4.3.5: immutable@4.3.7:
resolution: {integrity: sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==} resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==}
immutable@5.1.1: immutable@5.1.1:
resolution: {integrity: sha512-3jatXi9ObIsPGr3N5hGw/vWWcTkq6hUYhpQz4k0wLC+owqWi/LiugIw9x0EdNZ2yGedKN/HzePiBvaJRXa0Ujg==} resolution: {integrity: sha512-3jatXi9ObIsPGr3N5hGw/vWWcTkq6hUYhpQz4k0wLC+owqWi/LiugIw9x0EdNZ2yGedKN/HzePiBvaJRXa0Ujg==}
@ -2393,6 +2444,10 @@ packages:
resolution: {integrity: sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==} resolution: {integrity: sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==}
hasBin: true hasBin: true
math-intrinsics@1.1.0:
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
engines: {node: '>= 0.4'}
md5.js@1.3.5: md5.js@1.3.5:
resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==}
@ -2547,6 +2602,9 @@ packages:
nan@2.19.0: nan@2.19.0:
resolution: {integrity: sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==} resolution: {integrity: sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==}
nan@2.22.2:
resolution: {integrity: sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==}
nanoid@3.3.11: nanoid@3.3.11:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@ -2632,6 +2690,10 @@ packages:
object-inspect@1.13.1: object-inspect@1.13.1:
resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==}
object-inspect@1.13.4:
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
engines: {node: '>= 0.4'}
object-keys@1.1.1: object-keys@1.1.1:
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
@ -2640,8 +2702,8 @@ packages:
resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
object.assign@4.1.5: object.assign@4.1.7:
resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
object.pick@1.3.0: object.pick@1.3.0:
@ -2902,8 +2964,8 @@ packages:
pump@2.0.1: pump@2.0.1:
resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==}
pump@3.0.0: pump@3.0.2:
resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==}
pumpify@1.5.1: pumpify@1.5.1:
resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==}
@ -2923,6 +2985,10 @@ packages:
resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
engines: {node: '>=0.6'} engines: {node: '>=0.6'}
qs@6.14.0:
resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
engines: {node: '>=0.6'}
quasar@2.18.1: quasar@2.18.1:
resolution: {integrity: sha512-db/P64Mzpt1uXJ0MapaG+IYJQ9hHDb5KtTCoszwC78DR7sA+Uoj7nBW2EytwYykIExEmqavOvKrdasTvqhkgEg==} resolution: {integrity: sha512-db/P64Mzpt1uXJ0MapaG+IYJQ9hHDb5KtTCoszwC78DR7sA+Uoj7nBW2EytwYykIExEmqavOvKrdasTvqhkgEg==}
engines: {node: '>= 10.18.1', npm: '>= 6.13.4', yarn: '>= 1.21.1'} engines: {node: '>= 10.18.1', npm: '>= 6.13.4', yarn: '>= 1.21.1'}
@ -3298,10 +3364,26 @@ packages:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'} engines: {node: '>=8'}
side-channel-list@1.0.0:
resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
engines: {node: '>= 0.4'}
side-channel-map@1.0.1:
resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
engines: {node: '>= 0.4'}
side-channel-weakmap@1.0.2:
resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
engines: {node: '>= 0.4'}
side-channel@1.0.6: side-channel@1.0.6:
resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
side-channel@1.1.0:
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
engines: {node: '>= 0.4'}
signal-exit@3.0.7: signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
@ -4034,7 +4116,7 @@ snapshots:
'@eslint/config-array@0.19.2': '@eslint/config-array@0.19.2':
dependencies: dependencies:
'@eslint/object-schema': 2.1.6 '@eslint/object-schema': 2.1.6
debug: 4.3.4 debug: 4.4.0
minimatch: 3.1.2 minimatch: 3.1.2
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
@ -4048,7 +4130,7 @@ snapshots:
'@eslint/eslintrc@3.3.1': '@eslint/eslintrc@3.3.1':
dependencies: dependencies:
ajv: 6.12.6 ajv: 6.12.6
debug: 4.3.4 debug: 4.4.0
espree: 10.3.0 espree: 10.3.0
globals: 14.0.0 globals: 14.0.0
ignore: 5.3.2 ignore: 5.3.2
@ -4422,6 +4504,8 @@ snapshots:
'@types/estree@1.0.6': {} '@types/estree@1.0.6': {}
'@types/estree@1.0.7': {}
'@types/express-serve-static-core@4.19.0': '@types/express-serve-static-core@4.19.0':
dependencies: dependencies:
'@types/node': 20.16.1 '@types/node': 20.16.1
@ -4854,13 +4938,13 @@ snapshots:
asn1.js@4.10.1: asn1.js@4.10.1:
dependencies: dependencies:
bn.js: 4.12.0 bn.js: 4.12.1
inherits: 2.0.4 inherits: 2.0.4
minimalistic-assert: 1.0.1 minimalistic-assert: 1.0.1
assert@1.5.1: assert@1.5.1:
dependencies: dependencies:
object.assign: 4.1.5 object.assign: 4.1.7
util: 0.10.4 util: 0.10.4
assign-symbols@1.0.0: {} assign-symbols@1.0.0: {}
@ -4877,7 +4961,7 @@ snapshots:
autoprefixer@10.4.20(postcss@8.5.3): autoprefixer@10.4.20(postcss@8.5.3):
dependencies: dependencies:
browserslist: 4.23.3 browserslist: 4.23.3
caniuse-lite: 1.0.30001651 caniuse-lite: 1.0.30001707
fraction.js: 4.3.7 fraction.js: 4.3.7
normalize-range: 0.1.2 normalize-range: 0.1.2
picocolors: 1.0.1 picocolors: 1.0.1
@ -4935,7 +5019,7 @@ snapshots:
bmp-js@0.1.0: {} bmp-js@0.1.0: {}
bn.js@4.12.0: {} bn.js@4.12.1: {}
bn.js@5.2.1: {} bn.js@5.2.1: {}
@ -4989,7 +5073,7 @@ snapshots:
browserify-aes@1.2.0: browserify-aes@1.2.0:
dependencies: dependencies:
buffer-xor: 1.0.3 buffer-xor: 1.0.3
cipher-base: 1.0.4 cipher-base: 1.0.6
create-hash: 1.2.0 create-hash: 1.2.0
evp_bytestokey: 1.0.3 evp_bytestokey: 1.0.3
inherits: 2.0.4 inherits: 2.0.4
@ -5003,24 +5087,25 @@ snapshots:
browserify-des@1.0.2: browserify-des@1.0.2:
dependencies: dependencies:
cipher-base: 1.0.4 cipher-base: 1.0.6
des.js: 1.1.0 des.js: 1.1.0
inherits: 2.0.4 inherits: 2.0.4
safe-buffer: 5.2.1 safe-buffer: 5.2.1
browserify-rsa@4.1.0: browserify-rsa@4.1.1:
dependencies: dependencies:
bn.js: 5.2.1 bn.js: 5.2.1
randombytes: 2.1.0 randombytes: 2.1.0
safe-buffer: 5.2.1
browserify-sign@4.2.3: browserify-sign@4.2.3:
dependencies: dependencies:
bn.js: 5.2.1 bn.js: 5.2.1
browserify-rsa: 4.1.0 browserify-rsa: 4.1.1
create-hash: 1.2.0 create-hash: 1.2.0
create-hmac: 1.1.7 create-hmac: 1.1.7
elliptic: 6.5.7 elliptic: 6.6.1
hash-base: 3.0.4 hash-base: 3.0.5
inherits: 2.0.4 inherits: 2.0.4
parse-asn1: 5.1.7 parse-asn1: 5.1.7
readable-stream: 2.3.8 readable-stream: 2.3.8
@ -5032,7 +5117,7 @@ snapshots:
browserslist@4.23.3: browserslist@4.23.3:
dependencies: dependencies:
caniuse-lite: 1.0.30001651 caniuse-lite: 1.0.30001707
electron-to-chromium: 1.5.13 electron-to-chromium: 1.5.13
node-releases: 2.0.18 node-releases: 2.0.18
update-browserslist-db: 1.1.0(browserslist@4.23.3) update-browserslist-db: 1.1.0(browserslist@4.23.3)
@ -5099,6 +5184,11 @@ snapshots:
union-value: 1.0.1 union-value: 1.0.1
unset-value: 1.0.0 unset-value: 1.0.0
call-bind-apply-helpers@1.0.2:
dependencies:
es-errors: 1.3.0
function-bind: 1.1.2
call-bind@1.0.7: call-bind@1.0.7:
dependencies: dependencies:
es-define-property: 1.0.0 es-define-property: 1.0.0
@ -5107,6 +5197,18 @@ snapshots:
get-intrinsic: 1.2.4 get-intrinsic: 1.2.4
set-function-length: 1.2.2 set-function-length: 1.2.2
call-bind@1.0.8:
dependencies:
call-bind-apply-helpers: 1.0.2
es-define-property: 1.0.1
get-intrinsic: 1.3.0
set-function-length: 1.2.2
call-bound@1.0.4:
dependencies:
call-bind-apply-helpers: 1.0.2
get-intrinsic: 1.3.0
callsites@3.1.0: {} callsites@3.1.0: {}
camel-case@4.1.2: camel-case@4.1.2:
@ -5114,7 +5216,7 @@ snapshots:
pascal-case: 3.1.2 pascal-case: 3.1.2
tslib: 2.6.2 tslib: 2.6.2
caniuse-lite@1.0.30001651: {} caniuse-lite@1.0.30001707: {}
canvas@2.11.2: canvas@2.11.2:
dependencies: dependencies:
@ -5173,7 +5275,7 @@ snapshots:
ci-info@4.0.0: {} ci-info@4.0.0: {}
cipher-base@1.0.4: cipher-base@1.0.6:
dependencies: dependencies:
inherits: 2.0.4 inherits: 2.0.4
safe-buffer: 5.2.1 safe-buffer: 5.2.1
@ -5313,12 +5415,12 @@ snapshots:
create-ecdh@4.0.4: create-ecdh@4.0.4:
dependencies: dependencies:
bn.js: 4.12.0 bn.js: 4.12.1
elliptic: 6.5.7 elliptic: 6.6.1
create-hash@1.2.0: create-hash@1.2.0:
dependencies: dependencies:
cipher-base: 1.0.4 cipher-base: 1.0.6
inherits: 2.0.4 inherits: 2.0.4
md5.js: 1.3.5 md5.js: 1.3.5
ripemd160: 2.0.2 ripemd160: 2.0.2
@ -5326,7 +5428,7 @@ snapshots:
create-hmac@1.1.7: create-hmac@1.1.7:
dependencies: dependencies:
cipher-base: 1.0.4 cipher-base: 1.0.6
create-hash: 1.2.0 create-hash: 1.2.0
inherits: 2.0.4 inherits: 2.0.4
ripemd160: 2.0.2 ripemd160: 2.0.2
@ -5341,7 +5443,7 @@ snapshots:
shebang-command: 2.0.0 shebang-command: 2.0.0
which: 2.0.2 which: 2.0.2
crypto-browserify@3.12.0: crypto-browserify@3.12.1:
dependencies: dependencies:
browserify-cipher: 1.0.1 browserify-cipher: 1.0.1
browserify-sign: 4.2.3 browserify-sign: 4.2.3
@ -5349,6 +5451,7 @@ snapshots:
create-hash: 1.2.0 create-hash: 1.2.0
create-hmac: 1.1.7 create-hmac: 1.1.7
diffie-hellman: 5.0.3 diffie-hellman: 5.0.3
hash-base: 3.0.5
inherits: 2.0.4 inherits: 2.0.4
pbkdf2: 3.1.2 pbkdf2: 3.1.2
public-encrypt: 4.0.3 public-encrypt: 4.0.3
@ -5371,6 +5474,10 @@ snapshots:
dependencies: dependencies:
ms: 2.1.2 ms: 2.1.2
debug@4.4.0:
dependencies:
ms: 2.1.3
decode-uri-component@0.2.2: {} decode-uri-component@0.2.2: {}
decompress-response@4.2.1: decompress-response@4.2.1:
@ -5439,7 +5546,7 @@ snapshots:
diffie-hellman@5.0.3: diffie-hellman@5.0.3:
dependencies: dependencies:
bn.js: 4.12.0 bn.js: 4.12.1
miller-rabin: 4.0.1 miller-rabin: 4.0.1
randombytes: 2.1.0 randombytes: 2.1.0
@ -5460,6 +5567,12 @@ snapshots:
dotenv@16.4.7: {} dotenv@16.4.7: {}
dunder-proto@1.0.1:
dependencies:
call-bind-apply-helpers: 1.0.2
es-errors: 1.3.0
gopd: 1.2.0
duplexify@3.7.1: duplexify@3.7.1:
dependencies: dependencies:
end-of-stream: 1.4.4 end-of-stream: 1.4.4
@ -5477,9 +5590,9 @@ snapshots:
dependencies: dependencies:
sax: 1.1.4 sax: 1.1.4
elliptic@6.5.7: elliptic@6.6.1:
dependencies: dependencies:
bn.js: 4.12.0 bn.js: 4.12.1
brorand: 1.1.0 brorand: 1.1.0
hash.js: 1.1.7 hash.js: 1.1.7
hmac-drbg: 1.0.1 hmac-drbg: 1.0.1
@ -5535,8 +5648,14 @@ snapshots:
dependencies: dependencies:
get-intrinsic: 1.2.4 get-intrinsic: 1.2.4
es-define-property@1.0.1: {}
es-errors@1.3.0: {} es-errors@1.3.0: {}
es-object-atoms@1.1.1:
dependencies:
es-errors: 1.3.0
esbuild@0.25.1: esbuild@0.25.1:
optionalDependencies: optionalDependencies:
'@esbuild/aix-ppc64': 0.25.1 '@esbuild/aix-ppc64': 0.25.1
@ -5606,12 +5725,12 @@ snapshots:
'@humanfs/node': 0.16.6 '@humanfs/node': 0.16.6
'@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/module-importer': 1.0.1
'@humanwhocodes/retry': 0.4.2 '@humanwhocodes/retry': 0.4.2
'@types/estree': 1.0.6 '@types/estree': 1.0.7
'@types/json-schema': 7.0.15 '@types/json-schema': 7.0.15
ajv: 6.12.6 ajv: 6.12.6
chalk: 4.1.2 chalk: 4.1.2
cross-spawn: 7.0.6 cross-spawn: 7.0.6
debug: 4.3.4 debug: 4.4.0
escape-string-regexp: 4.0.0 escape-string-regexp: 4.0.0
eslint-scope: 8.3.0 eslint-scope: 8.3.0
eslint-visitor-keys: 4.2.0 eslint-visitor-keys: 4.2.0
@ -5888,7 +6007,7 @@ snapshots:
fsevents@1.2.13: fsevents@1.2.13:
dependencies: dependencies:
bindings: 1.5.0 bindings: 1.5.0
nan: 2.19.0 nan: 2.22.2
optional: true optional: true
fsevents@2.3.2: fsevents@2.3.2:
@ -5922,6 +6041,24 @@ snapshots:
has-symbols: 1.0.3 has-symbols: 1.0.3
hasown: 2.0.2 hasown: 2.0.2
get-intrinsic@1.3.0:
dependencies:
call-bind-apply-helpers: 1.0.2
es-define-property: 1.0.1
es-errors: 1.3.0
es-object-atoms: 1.1.1
function-bind: 1.1.2
get-proto: 1.0.1
gopd: 1.2.0
has-symbols: 1.1.0
hasown: 2.0.2
math-intrinsics: 1.1.0
get-proto@1.0.1:
dependencies:
dunder-proto: 1.0.1
es-object-atoms: 1.1.1
get-value@2.0.6: {} get-value@2.0.6: {}
glob-parent@3.1.0: glob-parent@3.1.0:
@ -5962,6 +6099,8 @@ snapshots:
dependencies: dependencies:
get-intrinsic: 1.2.4 get-intrinsic: 1.2.4
gopd@1.2.0: {}
graceful-fs@4.2.11: {} graceful-fs@4.2.11: {}
has-flag@4.0.0: {} has-flag@4.0.0: {}
@ -5974,6 +6113,8 @@ snapshots:
has-symbols@1.0.3: {} has-symbols@1.0.3: {}
has-symbols@1.1.0: {}
has-unicode@2.0.1: has-unicode@2.0.1:
optional: true optional: true
@ -5996,17 +6137,11 @@ snapshots:
is-number: 3.0.0 is-number: 3.0.0
kind-of: 4.0.0 kind-of: 4.0.0
hash-base@3.0.4: hash-base@3.0.5:
dependencies: dependencies:
inherits: 2.0.4 inherits: 2.0.4
safe-buffer: 5.2.1 safe-buffer: 5.2.1
hash-base@3.1.0:
dependencies:
inherits: 2.0.4
readable-stream: 3.6.2
safe-buffer: 5.2.1
hash.js@1.1.7: hash.js@1.1.7:
dependencies: dependencies:
inherits: 2.0.4 inherits: 2.0.4
@ -6068,7 +6203,7 @@ snapshots:
ignore@5.3.2: {} ignore@5.3.2: {}
immutable@4.3.5: immutable@4.3.7:
optional: true optional: true
immutable@5.1.1: {} immutable@5.1.1: {}
@ -6407,9 +6542,11 @@ snapshots:
mdurl: 1.0.1 mdurl: 1.0.1
uc.micro: 1.0.6 uc.micro: 1.0.6
math-intrinsics@1.1.0: {}
md5.js@1.3.5: md5.js@1.3.5:
dependencies: dependencies:
hash-base: 3.1.0 hash-base: 3.0.5
inherits: 2.0.4 inherits: 2.0.4
safe-buffer: 5.2.1 safe-buffer: 5.2.1
@ -6460,7 +6597,7 @@ snapshots:
miller-rabin@4.0.1: miller-rabin@4.0.1:
dependencies: dependencies:
bn.js: 4.12.0 bn.js: 4.12.1
brorand: 1.1.0 brorand: 1.1.0
mime-db@1.52.0: {} mime-db@1.52.0: {}
@ -6524,7 +6661,7 @@ snapshots:
flush-write-stream: 1.1.1 flush-write-stream: 1.1.1
from2: 2.3.0 from2: 2.3.0
parallel-transform: 1.2.0 parallel-transform: 1.2.0
pump: 3.0.0 pump: 3.0.2
pumpify: 1.5.1 pumpify: 1.5.1
stream-each: 1.2.3 stream-each: 1.2.3
through2: 2.0.5 through2: 2.0.5
@ -6572,6 +6709,9 @@ snapshots:
nan@2.19.0: nan@2.19.0:
optional: true optional: true
nan@2.22.2:
optional: true
nanoid@3.3.11: {} nanoid@3.3.11: {}
nanoid@3.3.7: {} nanoid@3.3.7: {}
@ -6618,7 +6758,7 @@ snapshots:
buffer: 4.9.2 buffer: 4.9.2
console-browserify: 1.2.0 console-browserify: 1.2.0
constants-browserify: 1.0.0 constants-browserify: 1.0.0
crypto-browserify: 3.12.0 crypto-browserify: 3.12.1
domain-browser: 1.2.0 domain-browser: 1.2.0
events: 3.3.0 events: 3.3.0
https-browserify: 1.0.0 https-browserify: 1.0.0
@ -6674,17 +6814,21 @@ snapshots:
object-inspect@1.13.1: {} object-inspect@1.13.1: {}
object-inspect@1.13.4: {}
object-keys@1.1.1: {} object-keys@1.1.1: {}
object-visit@1.0.1: object-visit@1.0.1:
dependencies: dependencies:
isobject: 3.0.1 isobject: 3.0.1
object.assign@4.1.5: object.assign@4.1.7:
dependencies: dependencies:
call-bind: 1.0.7 call-bind: 1.0.8
call-bound: 1.0.4
define-properties: 1.2.1 define-properties: 1.2.1
has-symbols: 1.0.3 es-object-atoms: 1.1.1
has-symbols: 1.1.0
object-keys: 1.1.1 object-keys: 1.1.1
object.pick@1.3.0: object.pick@1.3.0:
@ -6791,7 +6935,7 @@ snapshots:
asn1.js: 4.10.1 asn1.js: 4.10.1
browserify-aes: 1.2.0 browserify-aes: 1.2.0
evp_bytestokey: 1.0.3 evp_bytestokey: 1.0.3
hash-base: 3.0.4 hash-base: 3.0.5
pbkdf2: 3.1.2 pbkdf2: 3.1.2
safe-buffer: 5.2.1 safe-buffer: 5.2.1
@ -6926,8 +7070,8 @@ snapshots:
public-encrypt@4.0.3: public-encrypt@4.0.3:
dependencies: dependencies:
bn.js: 4.12.0 bn.js: 4.12.1
browserify-rsa: 4.1.0 browserify-rsa: 4.1.1
create-hash: 1.2.0 create-hash: 1.2.0
parse-asn1: 5.1.7 parse-asn1: 5.1.7
randombytes: 2.1.0 randombytes: 2.1.0
@ -6938,7 +7082,7 @@ snapshots:
end-of-stream: 1.4.4 end-of-stream: 1.4.4
once: 1.4.0 once: 1.4.0
pump@3.0.0: pump@3.0.2:
dependencies: dependencies:
end-of-stream: 1.4.4 end-of-stream: 1.4.4
once: 1.4.0 once: 1.4.0
@ -6959,6 +7103,10 @@ snapshots:
dependencies: dependencies:
side-channel: 1.0.6 side-channel: 1.0.6
qs@6.14.0:
dependencies:
side-channel: 1.1.0
quasar@2.18.1: {} quasar@2.18.1: {}
querystring-es3@0.2.1: {} querystring-es3@0.2.1: {}
@ -7074,7 +7222,7 @@ snapshots:
ripemd160@2.0.2: ripemd160@2.0.2:
dependencies: dependencies:
hash-base: 3.1.0 hash-base: 3.0.5
inherits: 2.0.4 inherits: 2.0.4
rollup-plugin-visualizer@5.14.0(rollup@4.37.0): rollup-plugin-visualizer@5.14.0(rollup@4.37.0):
@ -7233,7 +7381,7 @@ snapshots:
sass@1.77.8: sass@1.77.8:
dependencies: dependencies:
chokidar: 3.6.0 chokidar: 3.6.0
immutable: 4.3.5 immutable: 4.3.7
source-map-js: 1.2.1 source-map-js: 1.2.1
optional: true optional: true
@ -7346,6 +7494,26 @@ snapshots:
shebang-regex@3.0.0: {} shebang-regex@3.0.0: {}
side-channel-list@1.0.0:
dependencies:
es-errors: 1.3.0
object-inspect: 1.13.4
side-channel-map@1.0.1:
dependencies:
call-bound: 1.0.4
es-errors: 1.3.0
get-intrinsic: 1.3.0
object-inspect: 1.13.4
side-channel-weakmap@1.0.2:
dependencies:
call-bound: 1.0.4
es-errors: 1.3.0
get-intrinsic: 1.3.0
object-inspect: 1.13.4
side-channel-map: 1.0.1
side-channel@1.0.6: side-channel@1.0.6:
dependencies: dependencies:
call-bind: 1.0.7 call-bind: 1.0.7
@ -7353,6 +7521,14 @@ snapshots:
get-intrinsic: 1.2.4 get-intrinsic: 1.2.4
object-inspect: 1.13.1 object-inspect: 1.13.1
side-channel@1.1.0:
dependencies:
es-errors: 1.3.0
object-inspect: 1.13.4
side-channel-list: 1.0.0
side-channel-map: 1.0.1
side-channel-weakmap: 1.0.2
signal-exit@3.0.7: {} signal-exit@3.0.7: {}
signal-exit@4.1.0: {} signal-exit@4.1.0: {}
@ -7730,7 +7906,7 @@ snapshots:
url@0.11.4: url@0.11.4:
dependencies: dependencies:
punycode: 1.4.1 punycode: 1.4.1
qs: 6.13.0 qs: 6.14.0
use@3.1.1: {} use@3.1.1: {}

View file

@ -4,7 +4,7 @@ import { useQuasar } from 'quasar';
import SignaturePad from 'signature_pad'; import SignaturePad from 'signature_pad';
import Cropper from 'cropperjs'; import Cropper from 'cropperjs';
defineExpose({ clearCanvas, clearUpload }); defineExpose({ setCanvas, getCanvas, clearCanvas, clearUpload });
const $q = useQuasar(); const $q = useQuasar();
const isDarkActive = computed(() => $q.dark.isActive); const isDarkActive = computed(() => $q.dark.isActive);
@ -18,7 +18,7 @@ const cropper = ref();
const tab = ref('draw'); const tab = ref('draw');
const uploadFile = ref<File | undefined>(undefined); const uploadFile = ref<File | undefined>(undefined);
const profileUrl = ref<string | null>(''); const imgUrl = ref<string | null>('');
const inputFile = (() => { const inputFile = (() => {
const element = document.createElement('input'); const element = document.createElement('input');
element.type = 'file'; element.type = 'file';
@ -26,7 +26,7 @@ const inputFile = (() => {
const reader = new FileReader(); const reader = new FileReader();
reader.addEventListener('load', () => { reader.addEventListener('load', () => {
if (typeof reader.result === 'string') profileUrl.value = reader.result; if (typeof reader.result === 'string') imgUrl.value = reader.result;
}); });
element.addEventListener('change', () => { element.addEventListener('change', () => {
@ -39,12 +39,11 @@ const inputFile = (() => {
return element; return element;
})(); })();
async function initializeSignaturePad(canva?: HTMLCanvasElement) { async function initializeSignaturePad() {
if (canva) { const canvas = canvasRef.value;
signaturePad.value = new SignaturePad(canva, {
backgroundColor: isDarkActive.value if (canvas) {
? 'rgb(21,25,29)' signaturePad.value = new SignaturePad(canvas, {
: 'rgb(248,249,250)',
penColor: 'blue', penColor: 'blue',
}); });
} else { } else {
@ -77,34 +76,41 @@ function changeColor(color: string) {
currentColor.value = color; currentColor.value = color;
} }
function setCanvas() {
const data = signaturePad.value.toDataURL('image/png');
return data;
}
function getCanvas(signature: string) {
signaturePad.value.fromDataURL(signature);
}
function clearCanvas() { function clearCanvas() {
signaturePad.value.clear(); signaturePad.value.clear();
} }
function clearUpload() { function clearUpload() {
profileUrl.value = ''; imgUrl.value = '';
} }
watch( watch(
() => tab.value, () => tab.value,
async () => { async () => {
await initializeSignaturePad(canvasRef.value); await initializeSignaturePad();
await initializeCropper(imageRef.value);
}, },
); );
onMounted(async () => { onMounted(async () => {
await initializeSignaturePad(canvasRef.value); await initializeSignaturePad();
await initializeCropper(imageRef.value);
}); });
</script> </script>
<template> <template>
<div class="surface-1 bordered rounded full-width"> <div class="surface-1 column full-width full-height">
<q-tabs <q-tabs
v-model="tab" v-model="tab"
dense dense
align="left" align="left"
class="text-grey" class="text-grey surface-2"
active-color="primary" active-color="primary"
indicator-color="primary" indicator-color="primary"
> >
@ -112,18 +118,18 @@ onMounted(async () => {
<div class="row"> <div class="row">
<q-tab <q-tab
name="draw" name="draw"
label="Draw" :label="$t('general.draw')"
style="border-top-left-radius: var(--radius-2)" style="border-top-left-radius: var(--radius-2)"
/> />
<q-tab name="upload" label="Upload" /> <q-tab name="upload" :label="$t('general.upload')" />
</div> </div>
<div class="q-pr-md"> <div class="q-pr-md">
<q-btn <q-btn
v-if="tab === 'upload'"
dense dense
flat flat
v-if="tab === 'upload'" :label="$t('general.newUpload')"
:label="$t('newUpload')"
color="info" color="info"
@click="inputFile.click()" @click="inputFile.click()"
/> />
@ -132,89 +138,66 @@ onMounted(async () => {
</q-tabs> </q-tabs>
<q-separator /> <q-separator />
<div v-show="tab === 'draw'" class="q-pa-md"> <section v-show="tab === 'draw'" class="q-pa-md col">
<div class="column relative-position"> <div class="column relative-position">
<div class="absolute-top-right q-ma-md q-gutter-x-md row items-center"> <article
class="absolute-top-right q-ma-md q-gutter-x-md row items-center"
>
<span <span
v-for="color in ['black', 'red', 'blue']"
:key="color"
:class="{ active: currentColor === color }"
class="dot" class="dot"
:class="{ active: currentColor === 'black' }" :style="`background-color: ${color}`"
style="background-color: black" @click="changeColor(color)"
@click="changeColor('black')"
> >
<q-icon <q-icon
v-if="currentColor === 'black'" v-if="currentColor === color"
name="mdi-check" name="mdi-check"
color="white" color="white"
size="sm" size="sm"
/> />
</span> </span>
<span </article>
:class="{ active: currentColor === 'red' }"
class="dot"
style="background-color: red"
@click="changeColor('red')"
>
<q-icon
v-if="currentColor === 'red'"
name="mdi-check"
color="white"
size="sm"
/>
</span>
<span
:class="{ active: currentColor === 'blue' }"
class="dot"
style="background-color: blue"
@click="changeColor('blue')"
>
<q-icon
v-if="currentColor === 'blue'"
name="mdi-check"
color="white"
size="sm"
/>
</span>
</div>
<canvas <canvas
class="signature-canvas" class="signature-canvas"
ref="canvasRef" ref="canvasRef"
id="signature-pad" id="signature-pad"
width="700" width="766"
height="310" height="364"
></canvas> ></canvas>
</div> </div>
</div> </section>
<div v-show="tab === 'upload'" class="q-pa-md"> <section v-show="tab === 'upload'" class="q-pa-md col">
<div <div
class="bordered upload-border rounded column items-center justify-center" class="bordered upload-border rounded column items-center justify-center full-height"
style="height: 312px"
> >
<q-img <q-img
v-show="profileUrl" v-show="imgUrl"
ref="imageRef" ref="imageRef"
:src="profileUrl ?? ''" :src="imgUrl ?? ''"
style="object-fit: cover; width: 100%; height: 100%" style="object-fit: cover; width: 100%; height: 100%"
/> />
<div v-if="!profileUrl"> <div v-if="!imgUrl">
<q-icon <q-icon
name="mdi-cloud-upload" name="mdi-cloud-upload"
size="10rem" size="10rem"
style="color: hsla(var(--text-mute) / 0.2)" style="color: hsla(var(--text-mute) / 0.2)"
/> />
<div> <div class="text-center">
<q-btn <q-btn
unelevated unelevated
color="info" color="info"
:label="$t('uploadFile')" :label="$t('general.upload')"
icon="mdi-plus" icon="mdi-plus"
@click="inputFile.click()" @click="inputFile.click()"
/> />
</div> </div>
</div> </div>
</div> </div>
</div> </section>
</div> </div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">

View file

@ -151,6 +151,8 @@ export default {
dueDate: 'Due date', dueDate: 'Due date',
year: 'year', year: 'year',
tableOfContent: 'Table of Contents', tableOfContent: 'Table of Contents',
draw: 'Draw',
newUpload: 'New Upload',
}, },
menu: { menu: {

View file

@ -151,6 +151,8 @@ export default {
dueDate: 'วันครบกำหนด', dueDate: 'วันครบกำหนด',
year: 'ปี', year: 'ปี',
tableOfContent: 'สารบัญ', tableOfContent: 'สารบัญ',
draw: 'วาด',
newUpload: 'อัปโหลดใหม่',
}, },
menu: { menu: {

View file

@ -50,7 +50,6 @@ const leftDrawerMini = ref(false);
const unread = computed<number>( const unread = computed<number>(
() => notificationData.value.filter((v) => !v.read).length || 0, () => notificationData.value.filter((v) => !v.read).length || 0,
); );
// const filterRole = ref<string[]>();
const userImage = ref<string>(); const userImage = ref<string>();
const userGender = ref(''); const userGender = ref('');
const canvasRef = ref(); const canvasRef = ref();
@ -124,6 +123,17 @@ function readNoti(id: string) {
} }
} }
function signatureSubmit() {
const signature = canvasRef.value.setCanvas();
userStore.setSignature(signature);
canvasModal.value = false;
}
async function signatureFetch() {
const ret = await userStore.getSignature();
if (ret) canvasRef.value.getCanvas(ret);
}
onMounted(async () => { onMounted(async () => {
initTheme(); initTheme();
initLang(); initLang();
@ -502,13 +512,15 @@ onMounted(async () => {
no-app-box no-app-box
:title="$t('menu.profile.addSignature')" :title="$t('menu.profile.addSignature')"
:close="() => (canvasModal = false)" :close="() => (canvasModal = false)"
:submit="signatureSubmit"
:show="signatureFetch"
> >
<CanvasComponent ref="canvasRef" v-model:modal="canvasModal" /> <CanvasComponent ref="canvasRef" v-model:modal="canvasModal" />
<template #footer> <template #footer>
<q-btn <q-btn
flat flat
dense dense
:label="$t('clear')" :label="$t('general.clear')"
@click=" @click="
() => { () => {
canvasRef.clearCanvas(), canvasRef.clearUpload(); canvasRef.clearCanvas(), canvasRef.clearUpload();

View file

@ -31,7 +31,7 @@ const options = [
label: 'menu.profile.signature', label: 'menu.profile.signature',
value: 'signature', value: 'signature',
color: 'grey', color: 'grey',
disabled: true, disabled: false,
}, },
{ {
icon: 'mdi-brightness-6', icon: 'mdi-brightness-6',

View file

@ -15,6 +15,7 @@ import {
import axios from 'axios'; import axios from 'axios';
import useBranchStore from '../branch'; import useBranchStore from '../branch';
import { Branch } from '../branch/types'; import { Branch } from '../branch/types';
import { getSignature, setSignature } from './signature';
const branchStore = useBranchStore(); const branchStore = useBranchStore();
@ -327,6 +328,9 @@ const useUserStore = defineStore('api-user', () => {
addAttachment, addAttachment,
deleteAttachment, deleteAttachment,
getSignature,
setSignature,
typeStats, typeStats,
}; };
}); });

View file

@ -0,0 +1,50 @@
import axios from 'axios';
import { api } from 'src/boot/axios';
import { getUserId } from 'src/services/keycloak';
export async function getSignature() {
const userId = getUserId();
if (!userId) return;
const responseSignature = await api.get<string>(
'/user/' + userId + '/signature',
);
if (!responseSignature.data) return '';
const responseBlob = await axios.get<Blob>(responseSignature.data, {
responseType: 'blob',
});
if (responseBlob.status < 400) {
return await new Promise<string>((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener('error', reject);
reader.addEventListener('load', () => resolve(reader.result as string));
reader.readAsDataURL(responseBlob.data);
});
} else {
return '';
}
}
export async function setSignature(image: string) {
const userId = getUserId();
if (!userId) return;
if (image === '') {
return await deleteSignature();
} else {
return await api.put('/user/' + userId + '/signature', { data: image });
}
}
export async function deleteSignature() {
const userId = getUserId();
if (!userId) return;
return await api.delete('/user/' + userId + '/signature');
}