Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a914ea040c | |||
| f80e3679b6 |
Generated
+281
-218
@@ -9,17 +9,20 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pinia": "^4.0.0",
|
"pinia": "^4.0.0",
|
||||||
"vue": "^3.5.13"
|
"vue": "^3.5.13",
|
||||||
|
"vuetify": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tsconfig/node24": "^24.0.0",
|
"@tsconfig/node24": "^24.0.0",
|
||||||
"@types/node": "^24.0.0",
|
"@types/node": "^24.0.0",
|
||||||
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
"@vitest/coverage-v8": "^4.1.6",
|
"@vitest/coverage-v8": "^4.1.6",
|
||||||
"@vue/tsconfig": "^0.9.0",
|
"@vue/tsconfig": "^0.9.0",
|
||||||
"jsdom": "^29.1.1",
|
"jsdom": "^29.1.1",
|
||||||
"typescript": "~6.0.0",
|
"typescript": "~6.0.0",
|
||||||
"vite": "^8.0.0",
|
"vite": "^8.0.0",
|
||||||
"vitest": "^4.1.6"
|
"vitest": "^4.1.6",
|
||||||
|
"vue-tsc": "^3.0.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@asamuzakjp/css-color": {
|
"node_modules/@asamuzakjp/css-color": {
|
||||||
@@ -282,40 +285,6 @@
|
|||||||
"node": ">=20.19.0"
|
"node": ">=20.19.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@emnapi/core": {
|
|
||||||
"version": "1.11.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz",
|
|
||||||
"integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@emnapi/wasi-threads": "1.2.2",
|
|
||||||
"tslib": "^2.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@emnapi/runtime": {
|
|
||||||
"version": "1.11.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz",
|
|
||||||
"integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@emnapi/wasi-threads": {
|
|
||||||
"version": "1.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz",
|
|
||||||
"integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@exodus/bytes": {
|
"node_modules/@exodus/bytes": {
|
||||||
"version": "1.15.1",
|
"version": "1.15.1",
|
||||||
"resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.1.tgz",
|
||||||
@@ -361,39 +330,37 @@
|
|||||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@napi-rs/wasm-runtime": {
|
|
||||||
"version": "1.1.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz",
|
|
||||||
"integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@tybys/wasm-util": "^0.10.3"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/Brooooooklyn"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@emnapi/core": "^1.7.1",
|
|
||||||
"@emnapi/runtime": "^1.7.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@oxc-project/types": {
|
"node_modules/@oxc-project/types": {
|
||||||
"version": "0.139.0",
|
"version": "0.146.0",
|
||||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz",
|
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.146.0.tgz",
|
||||||
"integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==",
|
"integrity": "sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/Boshen"
|
"url": "https://github.com/sponsors/Boshen"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@rolldown/binding-android-arm-eabi": {
|
||||||
|
"version": "1.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.5.tgz",
|
||||||
|
"integrity": "sha512-DLe/i+l8ynIBY7XEQ191TeZvCoowIGa18R+dIV30GW7DiOtp74i/xX8hs8GUjW5ARV7VZuie3d6AumSmCwbeRA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rolldown/binding-android-arm64": {
|
"node_modules/@rolldown/binding-android-arm64": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.5.tgz",
|
||||||
"integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==",
|
"integrity": "sha512-zXcwKlQApYAOELHd8PwKDFkagYF9Wy4e0RJ+0qnzl9Pjnpj75TEG8ufv40p2J7kCEfwZAsNiuzRIyNNMWT38ig==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -408,9 +375,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-darwin-arm64": {
|
"node_modules/@rolldown/binding-darwin-arm64": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.5.tgz",
|
||||||
"integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==",
|
"integrity": "sha512-dK4QakI42nzWgJT5sm4y4y/O//D4OxM75/cH28RLV+nzIN9AY+YsbuUVrUTjlLjXR6vpyxFbSsbmNuJ6BP9sww==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -425,9 +392,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-darwin-x64": {
|
"node_modules/@rolldown/binding-darwin-x64": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.5.tgz",
|
||||||
"integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==",
|
"integrity": "sha512-fqSALaUu1Wjd1nK2uW2kJDWdLCc8lx1IcY+MTY26Aurfdx19anlzhqXOgCFbBFQnlFDTn4TC1/7Nz4Bl2mLP3A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -442,9 +409,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-freebsd-x64": {
|
"node_modules/@rolldown/binding-freebsd-x64": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.5.tgz",
|
||||||
"integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==",
|
"integrity": "sha512-/vCnNxlkxs9tKxNDcyWUePpJ/PgTzxIaVhoM5SmG8UV+GR/IcPam4VYxi7GIMo7PSDuNqlJqvprqii9NqqVCMw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -459,9 +426,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
|
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.5.tgz",
|
||||||
"integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==",
|
"integrity": "sha512-abk0NLA519LxRCszmbE0jYKuQ9YPocOXTiOXOo6Yr+YAT95VH+PtqYAjOJvGKt3viEd/x4qzabAlwd5bHOOARg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -476,9 +443,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-arm64-gnu": {
|
"node_modules/@rolldown/binding-linux-arm64-gnu": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.5.tgz",
|
||||||
"integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==",
|
"integrity": "sha512-Y7eALiJ8lr0M2HH103Js+g7V34wf6snlpZLAsHI90uLhr3PVlNsbFVAXJC9d/V6BnPyKtpSwI+NcB/RLxsQxuA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -493,9 +460,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-arm64-musl": {
|
"node_modules/@rolldown/binding-linux-arm64-musl": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.5.tgz",
|
||||||
"integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==",
|
"integrity": "sha512-xMvZgnbZg4YVnR/AX2b3oOPDTFYJvUVaJg5FedA/LuvexAtXibZQej4cnTkw3rjsJ/ggUROB64TdtETiim+FYA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -510,9 +477,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
|
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.5.tgz",
|
||||||
"integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==",
|
"integrity": "sha512-GRjeqTUDHTo5GwntsLaAMcBahG3nlpjftXWZLN73HiYQlhwEowvarFgQnRnQZtIp4keXX7quXFbG38uPZBa2EA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
@@ -527,9 +494,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-s390x-gnu": {
|
"node_modules/@rolldown/binding-linux-s390x-gnu": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.5.tgz",
|
||||||
"integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==",
|
"integrity": "sha512-vLNTR45F2Uwc8AufkNXPmB4VliaXs+FvcheEogIzOXzO4l+LzieXF5A/TWxLy5HtqpsRCHUfd0lPVrrdgXdLHQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
@@ -544,9 +511,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-x64-gnu": {
|
"node_modules/@rolldown/binding-linux-x64-gnu": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.5.tgz",
|
||||||
"integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==",
|
"integrity": "sha512-Mgj59/HTuYeK9Gz2MA+mBWKnHsAgkBSec15ZMb1st3oIfFbX7gCjOae7GydHhzcyQi9Z/7M1QuN9bR3oFqF0jQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -561,9 +528,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-x64-musl": {
|
"node_modules/@rolldown/binding-linux-x64-musl": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.5.tgz",
|
||||||
"integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==",
|
"integrity": "sha512-mY8AP0/ichsbhAxGnLa3d3+MwV0EfgrPND2bplI3Ym8T6R2pJ0N87bvrKVwNXmdy3jnr6eQBecdqx/HMknBmpA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -578,9 +545,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-openharmony-arm64": {
|
"node_modules/@rolldown/binding-openharmony-arm64": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.5.tgz",
|
||||||
"integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==",
|
"integrity": "sha512-8SLssA2oweAxyRgDp789ACfRb/3P+zNRJpzZxSizxF9m8NUDQ4+3xjo8ttjhVGGw6Qxb70oZiEtIjaKikCO7Yw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -594,29 +561,10 @@
|
|||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-wasm32-wasi": {
|
|
||||||
"version": "1.1.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz",
|
|
||||||
"integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==",
|
|
||||||
"cpu": [
|
|
||||||
"wasm32"
|
|
||||||
],
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@emnapi/core": "1.11.1",
|
|
||||||
"@emnapi/runtime": "1.11.1",
|
|
||||||
"@napi-rs/wasm-runtime": "^1.1.6"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^20.19.0 || >=22.12.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@rolldown/binding-win32-arm64-msvc": {
|
"node_modules/@rolldown/binding-win32-arm64-msvc": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.5.tgz",
|
||||||
"integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==",
|
"integrity": "sha512-vGbruD5zquhoc8D9SViXgN2FBJtNdTyQ4DtG+SWiEGlJiAzoKcZ2xp+xuXCffhubVdt0NJlTZqkeRuERy7g8Cw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -631,9 +579,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-win32-x64-msvc": {
|
"node_modules/@rolldown/binding-win32-x64-msvc": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.5.tgz",
|
||||||
"integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==",
|
"integrity": "sha512-e/SXpgISz+IoqVcSSI0rx/d/he8zqLex+/rCWpnHpmVfmPIUjag9H6P7zotf0gJHwPUhQxZ/mF8tr6acebT9yw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -668,17 +616,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@tybys/wasm-util": {
|
|
||||||
"version": "0.10.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz",
|
|
||||||
"integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true,
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.4.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/chai": {
|
"node_modules/@types/chai": {
|
||||||
"version": "5.2.3",
|
"version": "5.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
|
||||||
@@ -714,6 +651,23 @@
|
|||||||
"undici-types": "~7.18.0"
|
"undici-types": "~7.18.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@vitejs/plugin-vue": {
|
||||||
|
"version": "6.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.8.tgz",
|
||||||
|
"integrity": "sha512-0ZjgOg7oO6farnNGup7yvoM/YXZV84OZxHAwtflItNa/6zzQyVb5LNxyea3FEKEX2XlagIKzrlH7wwxkKgtiew==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@rolldown/pluginutils": "^1.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0",
|
||||||
|
"vue": "^3.2.25"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@vitest/coverage-v8": {
|
"node_modules/@vitest/coverage-v8": {
|
||||||
"version": "4.1.10",
|
"version": "4.1.10",
|
||||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.10.tgz",
|
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.10.tgz",
|
||||||
@@ -868,6 +822,35 @@
|
|||||||
"url": "https://opencollective.com/vitest"
|
"url": "https://opencollective.com/vitest"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@volar/language-core": {
|
||||||
|
"version": "2.4.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.28.tgz",
|
||||||
|
"integrity": "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@volar/source-map": "2.4.28"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@volar/source-map": {
|
||||||
|
"version": "2.4.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.28.tgz",
|
||||||
|
"integrity": "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@volar/typescript": {
|
||||||
|
"version": "2.4.28",
|
||||||
|
"resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.28.tgz",
|
||||||
|
"integrity": "sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@volar/language-core": "2.4.28",
|
||||||
|
"path-browserify": "^1.0.1",
|
||||||
|
"vscode-uri": "^3.0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@vue/compiler-core": {
|
"node_modules/@vue/compiler-core": {
|
||||||
"version": "3.5.40",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.40.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.40.tgz",
|
||||||
@@ -948,6 +931,22 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@vue/language-core": {
|
||||||
|
"version": "3.3.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.3.9.tgz",
|
||||||
|
"integrity": "sha512-in/68oAa4BCtVY6n/nkuhLIkV8DHYd2UivedJ6cMZ6UYtlq9jaoaSNUBHYCVO44z3nKg7MdE5OBoHKt5SxeBKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@volar/language-core": "2.4.28",
|
||||||
|
"@vue/compiler-dom": "^3.5.0",
|
||||||
|
"@vue/shared": "^3.5.0",
|
||||||
|
"alien-signals": "^3.2.1",
|
||||||
|
"muggle-string": "^0.4.1",
|
||||||
|
"path-browserify": "^1.0.1",
|
||||||
|
"picomatch": "^4.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@vue/reactivity": {
|
"node_modules/@vue/reactivity": {
|
||||||
"version": "3.5.40",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.40.tgz",
|
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.40.tgz",
|
||||||
@@ -1015,6 +1014,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/alien-signals": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/assertion-error": {
|
"node_modules/assertion-error": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
|
||||||
@@ -1335,9 +1341,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lightningcss": {
|
"node_modules/lightningcss": {
|
||||||
"version": "1.32.0",
|
"version": "1.33.0",
|
||||||
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz",
|
||||||
"integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
|
"integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1351,23 +1357,23 @@
|
|||||||
"url": "https://opencollective.com/parcel"
|
"url": "https://opencollective.com/parcel"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"lightningcss-android-arm64": "1.32.0",
|
"lightningcss-android-arm64": "1.33.0",
|
||||||
"lightningcss-darwin-arm64": "1.32.0",
|
"lightningcss-darwin-arm64": "1.33.0",
|
||||||
"lightningcss-darwin-x64": "1.32.0",
|
"lightningcss-darwin-x64": "1.33.0",
|
||||||
"lightningcss-freebsd-x64": "1.32.0",
|
"lightningcss-freebsd-x64": "1.33.0",
|
||||||
"lightningcss-linux-arm-gnueabihf": "1.32.0",
|
"lightningcss-linux-arm-gnueabihf": "1.33.0",
|
||||||
"lightningcss-linux-arm64-gnu": "1.32.0",
|
"lightningcss-linux-arm64-gnu": "1.33.0",
|
||||||
"lightningcss-linux-arm64-musl": "1.32.0",
|
"lightningcss-linux-arm64-musl": "1.33.0",
|
||||||
"lightningcss-linux-x64-gnu": "1.32.0",
|
"lightningcss-linux-x64-gnu": "1.33.0",
|
||||||
"lightningcss-linux-x64-musl": "1.32.0",
|
"lightningcss-linux-x64-musl": "1.33.0",
|
||||||
"lightningcss-win32-arm64-msvc": "1.32.0",
|
"lightningcss-win32-arm64-msvc": "1.33.0",
|
||||||
"lightningcss-win32-x64-msvc": "1.32.0"
|
"lightningcss-win32-x64-msvc": "1.33.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lightningcss-android-arm64": {
|
"node_modules/lightningcss-android-arm64": {
|
||||||
"version": "1.32.0",
|
"version": "1.33.0",
|
||||||
"resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz",
|
||||||
"integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
|
"integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1386,9 +1392,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lightningcss-darwin-arm64": {
|
"node_modules/lightningcss-darwin-arm64": {
|
||||||
"version": "1.32.0",
|
"version": "1.33.0",
|
||||||
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz",
|
||||||
"integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
|
"integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1407,9 +1413,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lightningcss-darwin-x64": {
|
"node_modules/lightningcss-darwin-x64": {
|
||||||
"version": "1.32.0",
|
"version": "1.33.0",
|
||||||
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz",
|
||||||
"integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
|
"integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1428,9 +1434,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lightningcss-freebsd-x64": {
|
"node_modules/lightningcss-freebsd-x64": {
|
||||||
"version": "1.32.0",
|
"version": "1.33.0",
|
||||||
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz",
|
||||||
"integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
|
"integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1449,9 +1455,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lightningcss-linux-arm-gnueabihf": {
|
"node_modules/lightningcss-linux-arm-gnueabihf": {
|
||||||
"version": "1.32.0",
|
"version": "1.33.0",
|
||||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz",
|
||||||
"integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
|
"integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -1470,9 +1476,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lightningcss-linux-arm64-gnu": {
|
"node_modules/lightningcss-linux-arm64-gnu": {
|
||||||
"version": "1.32.0",
|
"version": "1.33.0",
|
||||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz",
|
||||||
"integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
|
"integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1491,9 +1497,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lightningcss-linux-arm64-musl": {
|
"node_modules/lightningcss-linux-arm64-musl": {
|
||||||
"version": "1.32.0",
|
"version": "1.33.0",
|
||||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz",
|
||||||
"integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
|
"integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1512,9 +1518,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lightningcss-linux-x64-gnu": {
|
"node_modules/lightningcss-linux-x64-gnu": {
|
||||||
"version": "1.32.0",
|
"version": "1.33.0",
|
||||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz",
|
||||||
"integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
|
"integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1533,9 +1539,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lightningcss-linux-x64-musl": {
|
"node_modules/lightningcss-linux-x64-musl": {
|
||||||
"version": "1.32.0",
|
"version": "1.33.0",
|
||||||
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz",
|
||||||
"integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
|
"integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1554,9 +1560,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lightningcss-win32-arm64-msvc": {
|
"node_modules/lightningcss-win32-arm64-msvc": {
|
||||||
"version": "1.32.0",
|
"version": "1.33.0",
|
||||||
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz",
|
||||||
"integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
|
"integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -1575,9 +1581,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lightningcss-win32-x64-msvc": {
|
"node_modules/lightningcss-win32-x64-msvc": {
|
||||||
"version": "1.32.0",
|
"version": "1.33.0",
|
||||||
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
|
"resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz",
|
||||||
"integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
|
"integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1649,10 +1655,17 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "CC0-1.0"
|
"license": "CC0-1.0"
|
||||||
},
|
},
|
||||||
|
"node_modules/muggle-string": {
|
||||||
|
"version": "0.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz",
|
||||||
|
"integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/nanoid": {
|
"node_modules/nanoid": {
|
||||||
"version": "3.3.12",
|
"version": "3.3.18",
|
||||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz",
|
||||||
"integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
|
"integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
@@ -1713,6 +1726,13 @@
|
|||||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/path-browserify": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/pathe": {
|
"node_modules/pathe": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
|
||||||
@@ -1772,9 +1792,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.5.19",
|
"version": "8.5.26",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.19.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz",
|
||||||
"integrity": "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==",
|
"integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -1791,7 +1811,7 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.12",
|
"nanoid": "^3.3.17",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"source-map-js": "^1.2.1"
|
"source-map-js": "^1.2.1"
|
||||||
},
|
},
|
||||||
@@ -1820,13 +1840,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rolldown": {
|
"node_modules/rolldown": {
|
||||||
"version": "1.1.5",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.5.tgz",
|
||||||
"integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==",
|
"integrity": "sha512-VD2IE5PUG4Oj8zz2VGykiYd5wbnjdIiSsNQb8Qu5B+noEp+A78mu2iVvpp27g8es14Tk9rofNs5Tku9iQCS4fA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@oxc-project/types": "=0.139.0",
|
"@oxc-project/types": "=0.146.0",
|
||||||
"@rolldown/pluginutils": "^1.0.0"
|
"@rolldown/pluginutils": "^1.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -1836,21 +1856,21 @@
|
|||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@rolldown/binding-android-arm64": "1.1.5",
|
"@rolldown/binding-android-arm-eabi": "1.2.5",
|
||||||
"@rolldown/binding-darwin-arm64": "1.1.5",
|
"@rolldown/binding-android-arm64": "1.2.5",
|
||||||
"@rolldown/binding-darwin-x64": "1.1.5",
|
"@rolldown/binding-darwin-arm64": "1.2.5",
|
||||||
"@rolldown/binding-freebsd-x64": "1.1.5",
|
"@rolldown/binding-darwin-x64": "1.2.5",
|
||||||
"@rolldown/binding-linux-arm-gnueabihf": "1.1.5",
|
"@rolldown/binding-freebsd-x64": "1.2.5",
|
||||||
"@rolldown/binding-linux-arm64-gnu": "1.1.5",
|
"@rolldown/binding-linux-arm-gnueabihf": "1.2.5",
|
||||||
"@rolldown/binding-linux-arm64-musl": "1.1.5",
|
"@rolldown/binding-linux-arm64-gnu": "1.2.5",
|
||||||
"@rolldown/binding-linux-ppc64-gnu": "1.1.5",
|
"@rolldown/binding-linux-arm64-musl": "1.2.5",
|
||||||
"@rolldown/binding-linux-s390x-gnu": "1.1.5",
|
"@rolldown/binding-linux-ppc64-gnu": "1.2.5",
|
||||||
"@rolldown/binding-linux-x64-gnu": "1.1.5",
|
"@rolldown/binding-linux-s390x-gnu": "1.2.5",
|
||||||
"@rolldown/binding-linux-x64-musl": "1.1.5",
|
"@rolldown/binding-linux-x64-gnu": "1.2.5",
|
||||||
"@rolldown/binding-openharmony-arm64": "1.1.5",
|
"@rolldown/binding-linux-x64-musl": "1.2.5",
|
||||||
"@rolldown/binding-wasm32-wasi": "1.1.5",
|
"@rolldown/binding-openharmony-arm64": "1.2.5",
|
||||||
"@rolldown/binding-win32-arm64-msvc": "1.1.5",
|
"@rolldown/binding-win32-arm64-msvc": "1.2.5",
|
||||||
"@rolldown/binding-win32-x64-msvc": "1.1.5"
|
"@rolldown/binding-win32-x64-msvc": "1.2.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/saxes": {
|
"node_modules/saxes": {
|
||||||
@@ -2019,14 +2039,6 @@
|
|||||||
"node": ">=20"
|
"node": ">=20"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tslib": {
|
|
||||||
"version": "2.8.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
|
||||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "0BSD",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "6.0.3",
|
"version": "6.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
|
||||||
@@ -2059,16 +2071,16 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/vite": {
|
"node_modules/vite": {
|
||||||
"version": "8.1.5",
|
"version": "8.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-8.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz",
|
||||||
"integrity": "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==",
|
"integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lightningcss": "^1.32.0",
|
"lightningcss": "^1.33.0",
|
||||||
"picomatch": "^4.0.5",
|
"picomatch": "^4.0.5",
|
||||||
"postcss": "^8.5.17",
|
"postcss": "^8.5.26",
|
||||||
"rolldown": "~1.1.5",
|
"rolldown": "~1.2.4",
|
||||||
"tinyglobby": "^0.2.17"
|
"tinyglobby": "^0.2.17"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -2085,7 +2097,7 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@types/node": "^20.19.0 || >=22.12.0",
|
"@types/node": "^20.19.0 || >=22.12.0",
|
||||||
"@vitejs/devtools": "^0.3.0",
|
"@vitejs/devtools": "^0.4.0 || ^0.5.0",
|
||||||
"esbuild": "^0.27.0 || ^0.28.0",
|
"esbuild": "^0.27.0 || ^0.28.0",
|
||||||
"jiti": ">=1.21.0",
|
"jiti": ">=1.21.0",
|
||||||
"less": "^4.0.0",
|
"less": "^4.0.0",
|
||||||
@@ -2226,6 +2238,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vscode-uri": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/vue": {
|
"node_modules/vue": {
|
||||||
"version": "3.5.40",
|
"version": "3.5.40",
|
||||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.40.tgz",
|
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.40.tgz",
|
||||||
@@ -2247,6 +2266,50 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vue-tsc": {
|
||||||
|
"version": "3.3.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.3.9.tgz",
|
||||||
|
"integrity": "sha512-TS3Y1ux/IRoE8OCP2PpACAeOseuIs0UvWrcr7u+w3PmfY+SlCfEf8zjrBgnQksHUgLpthi5vHlffcQTQTdPBZA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@volar/typescript": "2.4.28",
|
||||||
|
"@vue/language-core": "3.3.9"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"vue-tsc": "bin/vue-tsc.js"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": ">=5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vuetify": {
|
||||||
|
"version": "4.1.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-4.1.9.tgz",
|
||||||
|
"integrity": "sha512-2NlpUiSwkUAGxKmkKwoRCst3IJF6EPP7msNJd+VxFjcAN9xCG+RFODzsfXfO2ypl9aSj3T/PJ65BBjQeTGgFKA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/johnleider"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": ">=4.7",
|
||||||
|
"vite-plugin-vuetify": ">=2.1.0",
|
||||||
|
"vue": "^3.5.0 || ^3.6.0-0",
|
||||||
|
"webpack-plugin-vuetify": ">=3.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"typescript": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"vite-plugin-vuetify": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"webpack-plugin-vuetify": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/w3c-xmlserializer": {
|
"node_modules/w3c-xmlserializer": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz",
|
||||||
|
|||||||
+4
-1
@@ -15,14 +15,17 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pinia": "^4.0.0",
|
"pinia": "^4.0.0",
|
||||||
"vue": "^3.5.13"
|
"vue": "^3.5.13",
|
||||||
|
"vuetify": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tsconfig/node24": "^24.0.0",
|
"@tsconfig/node24": "^24.0.0",
|
||||||
"@types/node": "^24.0.0",
|
"@types/node": "^24.0.0",
|
||||||
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
"@vue/tsconfig": "^0.9.0",
|
"@vue/tsconfig": "^0.9.0",
|
||||||
"typescript": "~6.0.0",
|
"typescript": "~6.0.0",
|
||||||
"vite": "^8.0.0",
|
"vite": "^8.0.0",
|
||||||
|
"vue-tsc": "^3.0.5",
|
||||||
"@vitest/coverage-v8": "^4.1.6",
|
"@vitest/coverage-v8": "^4.1.6",
|
||||||
"jsdom": "^29.1.1",
|
"jsdom": "^29.1.1",
|
||||||
"vitest": "^4.1.6"
|
"vitest": "^4.1.6"
|
||||||
|
|||||||
@@ -0,0 +1,228 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref, watch } from 'vue'
|
||||||
|
import { useDocumentManager, useDocumentSelection } from '@/composables'
|
||||||
|
import { CollectionObject } from '@/models/collection'
|
||||||
|
import { EntityObject } from '@/models/entity'
|
||||||
|
import { formatSize, getFileIcon } from '@/utils/fileHelpers'
|
||||||
|
|
||||||
|
export interface DocumentSelection {
|
||||||
|
kind: 'entity' | 'collection'
|
||||||
|
identifier: string
|
||||||
|
name: string
|
||||||
|
mimeType?: string
|
||||||
|
size?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const PROVIDER_ID = 'default'
|
||||||
|
const SERVICE_ID = 'personal'
|
||||||
|
const LARGE_FILE_WARNING_BYTES = 25 * 1024 * 1024
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
modelValue: boolean
|
||||||
|
selectable?: ('entity' | 'collection')[]
|
||||||
|
}>(), {
|
||||||
|
selectable: () => ['entity'],
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:modelValue': [value: boolean]
|
||||||
|
select: [items: DocumentSelection[]]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const allowEntities = computed(() => props.selectable.includes('entity'))
|
||||||
|
const allowCollections = computed(() => props.selectable.includes('collection'))
|
||||||
|
|
||||||
|
const documentManager = useDocumentManager({
|
||||||
|
providerId: PROVIDER_ID,
|
||||||
|
serviceId: SERVICE_ID,
|
||||||
|
})
|
||||||
|
|
||||||
|
const selection = useDocumentSelection({
|
||||||
|
multiple: true,
|
||||||
|
allowFolders: allowCollections.value,
|
||||||
|
allowFiles: allowEntities.value,
|
||||||
|
})
|
||||||
|
|
||||||
|
const initialized = ref(false)
|
||||||
|
|
||||||
|
watch(() => props.modelValue, async (isOpen) => {
|
||||||
|
if (!isOpen) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
selection.clear()
|
||||||
|
|
||||||
|
if (!initialized.value) {
|
||||||
|
await documentManager.initialize()
|
||||||
|
initialized.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
await documentManager.navigateToRoot()
|
||||||
|
})
|
||||||
|
|
||||||
|
function nodeId(node: CollectionObject | EntityObject): string {
|
||||||
|
return String(node.identifier ?? '')
|
||||||
|
}
|
||||||
|
|
||||||
|
function nodeLabel(node: CollectionObject | EntityObject): string {
|
||||||
|
return node.properties.label || nodeId(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
const breadcrumbs = computed(() => [
|
||||||
|
{ id: documentManager.ROOT_ID, label: 'Home' },
|
||||||
|
...documentManager.breadcrumbs.value.map(node => ({ id: nodeId(node), label: nodeLabel(node) })),
|
||||||
|
])
|
||||||
|
|
||||||
|
async function navigateToBreadcrumb(id: string) {
|
||||||
|
selection.clear()
|
||||||
|
await documentManager.navigateTo(id === documentManager.ROOT_ID ? null : id)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openFolder(folder: CollectionObject) {
|
||||||
|
selection.clear()
|
||||||
|
await documentManager.navigateTo(nodeId(folder))
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleFolderSelection(folder: CollectionObject, event: Event) {
|
||||||
|
event.stopPropagation()
|
||||||
|
selection.toggle(folder)
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleEntity(entity: EntityObject) {
|
||||||
|
selection.toggle(entity)
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasLargeSelection = computed(() =>
|
||||||
|
selection.selectedEntities.value.some(entity => entity.properties.size > LARGE_FILE_WARNING_BYTES),
|
||||||
|
)
|
||||||
|
|
||||||
|
function entityIdentifier(entity: EntityObject): string {
|
||||||
|
return `${entity.provider}:${entity.service}:${entity.collection}:${entity.identifier}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectionIdentifier(collection: CollectionObject): string {
|
||||||
|
return `${collection.provider}:${collection.service}:${collection.identifier}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function toSelection(node: CollectionObject | EntityObject): DocumentSelection {
|
||||||
|
if (node instanceof EntityObject) {
|
||||||
|
return {
|
||||||
|
kind: 'entity',
|
||||||
|
identifier: entityIdentifier(node),
|
||||||
|
name: nodeLabel(node),
|
||||||
|
mimeType: node.properties.mime || 'application/octet-stream',
|
||||||
|
size: node.properties.size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
kind: 'collection',
|
||||||
|
identifier: collectionIdentifier(node),
|
||||||
|
name: nodeLabel(node),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleClose() {
|
||||||
|
emit('update:modelValue', false)
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleConfirm() {
|
||||||
|
const items = selection.selectedNodeArray.value.map(toSelection)
|
||||||
|
if (items.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
emit('select', items)
|
||||||
|
selection.clear()
|
||||||
|
emit('update:modelValue', false)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<v-dialog :model-value="modelValue" @update:model-value="emit('update:modelValue', $event)" max-width="560">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title class="d-flex align-center">
|
||||||
|
<v-icon class="mr-2">mdi-folder-search-outline</v-icon>
|
||||||
|
Select Documents
|
||||||
|
</v-card-title>
|
||||||
|
|
||||||
|
<v-card-text>
|
||||||
|
<v-breadcrumbs :items="breadcrumbs" density="compact" class="px-0 mb-2">
|
||||||
|
<template #item="{ item }">
|
||||||
|
<v-breadcrumbs-item :disabled="item.id === breadcrumbs[breadcrumbs.length - 1]?.id" @click="navigateToBreadcrumb(item.id)">
|
||||||
|
{{ item.label }}
|
||||||
|
</v-breadcrumbs-item>
|
||||||
|
</template>
|
||||||
|
</v-breadcrumbs>
|
||||||
|
|
||||||
|
<v-progress-linear v-if="documentManager.isLoading.value" indeterminate color="primary" class="mb-2" />
|
||||||
|
|
||||||
|
<div class="selector-list">
|
||||||
|
<v-list v-if="documentManager.currentCollections.value.length > 0 || documentManager.currentEntities.value.length > 0" density="compact">
|
||||||
|
<v-list-item
|
||||||
|
v-for="folder in documentManager.currentCollections.value"
|
||||||
|
:key="nodeId(folder)"
|
||||||
|
:title="nodeLabel(folder)"
|
||||||
|
@click="openFolder(folder)"
|
||||||
|
>
|
||||||
|
<template #prepend>
|
||||||
|
<v-checkbox-btn
|
||||||
|
v-if="allowCollections"
|
||||||
|
:model-value="selection.isSelected(nodeId(folder))"
|
||||||
|
class="mr-2"
|
||||||
|
@click="toggleFolderSelection(folder, $event)"
|
||||||
|
/>
|
||||||
|
<v-icon>mdi-folder</v-icon>
|
||||||
|
</template>
|
||||||
|
<template #append>
|
||||||
|
<v-icon size="small">mdi-chevron-right</v-icon>
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
|
||||||
|
<v-list-item
|
||||||
|
v-for="entity in documentManager.currentEntities.value"
|
||||||
|
:key="nodeId(entity)"
|
||||||
|
:title="nodeLabel(entity)"
|
||||||
|
:subtitle="formatSize(entity.properties.size)"
|
||||||
|
:disabled="!allowEntities"
|
||||||
|
@click="allowEntities && toggleEntity(entity)"
|
||||||
|
>
|
||||||
|
<template #prepend>
|
||||||
|
<v-checkbox-btn v-if="allowEntities" :model-value="selection.isSelected(nodeId(entity))" class="mr-2" />
|
||||||
|
<v-icon>{{ getFileIcon(entity) }}</v-icon>
|
||||||
|
</template>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
|
||||||
|
<div v-else-if="!documentManager.isLoading.value" class="text-center py-8 text-medium-emphasis">
|
||||||
|
<v-icon size="40" class="mb-2">mdi-folder-open-outline</v-icon>
|
||||||
|
<div>This folder is empty</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<v-alert v-if="hasLargeSelection" type="warning" variant="tonal" density="compact" class="mt-3">
|
||||||
|
One or more selected files are larger than 25 MB and may take a moment to process.
|
||||||
|
</v-alert>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
<v-card-actions>
|
||||||
|
<span class="text-caption text-medium-emphasis ml-2">
|
||||||
|
{{ selection.count.value }} selected
|
||||||
|
</span>
|
||||||
|
<v-spacer />
|
||||||
|
<v-btn variant="text" @click="handleClose">Cancel</v-btn>
|
||||||
|
<v-btn color="primary" variant="elevated" :disabled="!selection.hasSelection.value" @click="handleConfirm">
|
||||||
|
Select
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.selector-list {
|
||||||
|
max-height: 360px;
|
||||||
|
overflow-y: auto;
|
||||||
|
border: 1px solid rgb(var(--v-border-color));
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
/**
|
||||||
|
* Central export point for Documents Manager composables
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { useDocumentManager } from './useDocumentManager'
|
||||||
|
export { useDocumentSelection } from './useDocumentSelection'
|
||||||
|
|
||||||
|
export type { UseDocumentManagerOptions } from './useDocumentManager'
|
||||||
|
export type { UseDocumentSelectionOptions } from './useDocumentSelection'
|
||||||
@@ -0,0 +1,295 @@
|
|||||||
|
/**
|
||||||
|
* File Manager composable for convenient file/folder operations
|
||||||
|
* Provides reactive access to file manager state and actions
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { computed, ref, unref } from 'vue'
|
||||||
|
import type { Ref, ComputedRef } from 'vue'
|
||||||
|
import { useProvidersStore } from '@/stores/providersStore'
|
||||||
|
import { useServicesStore } from '@/stores/servicesStore'
|
||||||
|
import { useNodesStore, ROOT_ID } from '@/stores/nodesStore'
|
||||||
|
import type { ListFilter, ListSort, ListRange } from '@/types/common'
|
||||||
|
import type { DocumentInterface } from '@/types/document'
|
||||||
|
import { CollectionObject } from '@/models/collection'
|
||||||
|
import { EntityObject } from '@/models/entity'
|
||||||
|
|
||||||
|
// Base URL for file manager transfer endpoints
|
||||||
|
const TRANSFER_BASE_URL = '/m/documents_manager'
|
||||||
|
|
||||||
|
export interface UseDocumentManagerOptions {
|
||||||
|
providerId: string | Ref<string> | ComputedRef<string>
|
||||||
|
serviceId: string | Ref<string> | ComputedRef<string>
|
||||||
|
autoFetch?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDocumentManager(options: UseDocumentManagerOptions) {
|
||||||
|
const providersStore = useProvidersStore()
|
||||||
|
const servicesStore = useServicesStore()
|
||||||
|
const nodesStore = useNodesStore()
|
||||||
|
|
||||||
|
const { providerId, serviceId, autoFetch = false } = options
|
||||||
|
|
||||||
|
const currentProviderId = () => unref(providerId)
|
||||||
|
const currentServiceId = () => unref(serviceId)
|
||||||
|
|
||||||
|
// Current location (folder being viewed)
|
||||||
|
const currentLocation: Ref<string> = ref(ROOT_ID)
|
||||||
|
|
||||||
|
// Loading/error state
|
||||||
|
const isLoading = computed(() => nodesStore.transceiving)
|
||||||
|
const error = computed(() => nodesStore.error)
|
||||||
|
|
||||||
|
// Provider and service
|
||||||
|
const provider = computed(() => providersStore.provider(currentProviderId()))
|
||||||
|
const service = computed(() => servicesStore.service(currentProviderId(), currentServiceId()))
|
||||||
|
const rootId = computed(() => ROOT_ID)
|
||||||
|
|
||||||
|
// Current children
|
||||||
|
const currentChildren = computed(() =>
|
||||||
|
nodesStore.getChildren(currentProviderId(), currentServiceId(), currentLocation.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
const currentCollections: ComputedRef<CollectionObject[]> = computed(() =>
|
||||||
|
nodesStore.getChildCollections(currentProviderId(), currentServiceId(), currentLocation.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
const currentEntities: ComputedRef<EntityObject[]> = computed(() =>
|
||||||
|
nodesStore.getChildEntities(currentProviderId(), currentServiceId(), currentLocation.value)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Breadcrumb path
|
||||||
|
const breadcrumbs = computed(() => {
|
||||||
|
if (currentLocation.value === ROOT_ID) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
return nodesStore.getPath(currentProviderId(), currentServiceId(), currentLocation.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Is at root?
|
||||||
|
const isAtRoot = computed(() => currentLocation.value === ROOT_ID)
|
||||||
|
|
||||||
|
// Navigate to a folder
|
||||||
|
const navigateTo = async (collectionId: string | null) => {
|
||||||
|
currentLocation.value = collectionId || ROOT_ID
|
||||||
|
await refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigate up one level
|
||||||
|
const navigateUp = async () => {
|
||||||
|
if (currentLocation.value === ROOT_ID) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const currentNode = nodesStore.getNode(currentProviderId(), currentServiceId(), currentLocation.value)
|
||||||
|
if (currentNode) {
|
||||||
|
await navigateTo(currentNode.collection ? String(currentNode.collection) : ROOT_ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigate to root
|
||||||
|
const navigateToRoot = async () => {
|
||||||
|
await navigateTo(ROOT_ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Refresh current location
|
||||||
|
const refresh = async (
|
||||||
|
filter?: ListFilter,
|
||||||
|
sort?: ListSort,
|
||||||
|
range?: ListRange
|
||||||
|
) => {
|
||||||
|
await nodesStore.fetchNodes(
|
||||||
|
currentProviderId(),
|
||||||
|
currentServiceId(),
|
||||||
|
currentLocation.value === ROOT_ID ? ROOT_ID : currentLocation.value,
|
||||||
|
filter,
|
||||||
|
sort,
|
||||||
|
range
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new folder
|
||||||
|
const createFolder = async (label: string): Promise<CollectionObject> => {
|
||||||
|
return await nodesStore.createCollection(
|
||||||
|
currentProviderId(),
|
||||||
|
currentServiceId(),
|
||||||
|
currentLocation.value === ROOT_ID ? ROOT_ID : currentLocation.value,
|
||||||
|
{ label, owner: '' }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new file
|
||||||
|
const createFile = async (
|
||||||
|
label: string,
|
||||||
|
mime: string = 'application/octet-stream'
|
||||||
|
): Promise<EntityObject> => {
|
||||||
|
const properties: DocumentInterface = {
|
||||||
|
'@type': 'documents.properties',
|
||||||
|
urid: null,
|
||||||
|
size: 0,
|
||||||
|
label,
|
||||||
|
mime,
|
||||||
|
format: null,
|
||||||
|
encoding: null,
|
||||||
|
}
|
||||||
|
|
||||||
|
return await nodesStore.createEntity(
|
||||||
|
currentProviderId(),
|
||||||
|
currentServiceId(),
|
||||||
|
currentLocation.value === ROOT_ID ? ROOT_ID : currentLocation.value,
|
||||||
|
properties
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rename a node
|
||||||
|
const renameNode = async (nodeId: string, newLabel: string) => {
|
||||||
|
const node = nodesStore.getNode(currentProviderId(), currentServiceId(), nodeId)
|
||||||
|
if (!node) {
|
||||||
|
throw new Error('Node not found')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node instanceof CollectionObject) {
|
||||||
|
return await nodesStore.updateCollection(currentProviderId(), currentServiceId(), nodeId, {
|
||||||
|
label: newLabel,
|
||||||
|
owner: node.properties.owner,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const properties: DocumentInterface = {
|
||||||
|
'@type': 'documents.properties',
|
||||||
|
urid: node.properties.urid,
|
||||||
|
size: node.properties.size,
|
||||||
|
label: newLabel,
|
||||||
|
mime: node.properties.mime,
|
||||||
|
format: node.properties.format,
|
||||||
|
encoding: node.properties.encoding,
|
||||||
|
}
|
||||||
|
return await nodesStore.updateEntity(currentProviderId(), currentServiceId(), node.collection, nodeId, properties)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete a node
|
||||||
|
const deleteNode = async (nodeId: string): Promise<boolean> => {
|
||||||
|
const node = nodesStore.getNode(currentProviderId(), currentServiceId(), nodeId)
|
||||||
|
if (!node) {
|
||||||
|
throw new Error('Node not found')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node instanceof CollectionObject) {
|
||||||
|
return await nodesStore.deleteCollection(currentProviderId(), currentServiceId(), nodeId)
|
||||||
|
} else {
|
||||||
|
return await nodesStore.deleteEntity(currentProviderId(), currentServiceId(), node.collection, nodeId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read file content
|
||||||
|
const readFile = async (entityId: string): Promise<string | null> => {
|
||||||
|
const node = nodesStore.getNode(currentProviderId(), currentServiceId(), entityId)
|
||||||
|
if (!node || !(node instanceof EntityObject)) {
|
||||||
|
throw new Error('Entity not found')
|
||||||
|
}
|
||||||
|
return await nodesStore.readEntity(currentProviderId(), currentServiceId(), node.collection || ROOT_ID, entityId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write file content
|
||||||
|
const writeFile = async (entityId: string, content: string): Promise<number> => {
|
||||||
|
const node = nodesStore.getNode(currentProviderId(), currentServiceId(), entityId)
|
||||||
|
if (!node || !(node instanceof EntityObject)) {
|
||||||
|
throw new Error('Entity not found')
|
||||||
|
}
|
||||||
|
return await nodesStore.writeEntity(currentProviderId(), currentServiceId(), node.collection, entityId, content)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a URL suitable for inline viewing (img src / video src)
|
||||||
|
const getEntityUrl = (entityId: string, collectionId?: string | null): string => {
|
||||||
|
const collection = collectionId ?? currentLocation.value
|
||||||
|
return `${TRANSFER_BASE_URL}/download/entity/${encodeURIComponent(currentProviderId())}/${encodeURIComponent(currentServiceId())}/${encodeURIComponent(collection)}/${encodeURIComponent(entityId)}`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Download a single file
|
||||||
|
const downloadEntity = (entityId: string, collectionId?: string | null): void => {
|
||||||
|
const collection = collectionId ?? currentLocation.value
|
||||||
|
// Use path parameters: /download/entity/{provider}/{service}/{collection}/{identifier}
|
||||||
|
const url = `${TRANSFER_BASE_URL}/download/entity/${encodeURIComponent(currentProviderId())}/${encodeURIComponent(currentServiceId())}/${encodeURIComponent(collection)}/${encodeURIComponent(entityId)}`
|
||||||
|
|
||||||
|
// Trigger download by opening URL (browser handles it)
|
||||||
|
window.open(url, '_blank')
|
||||||
|
}
|
||||||
|
|
||||||
|
const downloadCollection = (collectionId: string): void => {
|
||||||
|
// Use path parameters: /download/collection/{provider}/{service}/{identifier}
|
||||||
|
const url = `${TRANSFER_BASE_URL}/download/collection/${encodeURIComponent(currentProviderId())}/${encodeURIComponent(currentServiceId())}/${encodeURIComponent(collectionId)}`
|
||||||
|
|
||||||
|
window.open(url, '_blank')
|
||||||
|
}
|
||||||
|
|
||||||
|
const downloadArchive = (ids: string[], name: string = 'download', collectionId?: string | null): void => {
|
||||||
|
const collection = collectionId ?? currentLocation.value
|
||||||
|
const params = new URLSearchParams({
|
||||||
|
provider: currentProviderId(),
|
||||||
|
service: currentServiceId(),
|
||||||
|
})
|
||||||
|
ids.forEach(id => params.append('ids[]', id))
|
||||||
|
if (name) {
|
||||||
|
params.append('name', name)
|
||||||
|
}
|
||||||
|
if (collection && collection !== ROOT_ID) {
|
||||||
|
params.append('collection', collection)
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = `${TRANSFER_BASE_URL}/download/archive?${params.toString()}`
|
||||||
|
|
||||||
|
window.open(url, '_blank')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize - fetch providers, services, and initial nodes if autoFetch
|
||||||
|
const initialize = async () => {
|
||||||
|
await providersStore.list([currentProviderId()])
|
||||||
|
await servicesStore.list()
|
||||||
|
if (autoFetch) {
|
||||||
|
await refresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
// State
|
||||||
|
currentLocation,
|
||||||
|
isLoading,
|
||||||
|
error,
|
||||||
|
|
||||||
|
// Provider/Service
|
||||||
|
provider,
|
||||||
|
service,
|
||||||
|
rootId,
|
||||||
|
|
||||||
|
// Current view
|
||||||
|
currentChildren,
|
||||||
|
currentCollections,
|
||||||
|
currentEntities,
|
||||||
|
breadcrumbs,
|
||||||
|
isAtRoot,
|
||||||
|
|
||||||
|
// Navigation
|
||||||
|
navigateTo,
|
||||||
|
navigateUp,
|
||||||
|
navigateToRoot,
|
||||||
|
refresh,
|
||||||
|
|
||||||
|
// Operations
|
||||||
|
createFolder,
|
||||||
|
createFile,
|
||||||
|
renameNode,
|
||||||
|
deleteNode,
|
||||||
|
readFile,
|
||||||
|
writeFile,
|
||||||
|
getEntityUrl,
|
||||||
|
downloadEntity,
|
||||||
|
downloadCollection,
|
||||||
|
downloadArchive,
|
||||||
|
|
||||||
|
// Initialize
|
||||||
|
initialize,
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
ROOT_ID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useDocumentManager
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
/**
|
||||||
|
* File selection composable
|
||||||
|
* Provides reactive selection management for file manager
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import type { Ref, ComputedRef } from 'vue'
|
||||||
|
import { CollectionObject } from '@/models/collection'
|
||||||
|
import { EntityObject } from '@/models/entity'
|
||||||
|
|
||||||
|
type NodeRecord = CollectionObject | EntityObject
|
||||||
|
|
||||||
|
export interface UseDocumentSelectionOptions {
|
||||||
|
multiple?: boolean
|
||||||
|
allowFolders?: boolean
|
||||||
|
allowFiles?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDocumentSelection(options: UseDocumentSelectionOptions = {}) {
|
||||||
|
const {
|
||||||
|
multiple = true,
|
||||||
|
allowFolders = true,
|
||||||
|
allowFiles = true,
|
||||||
|
} = options
|
||||||
|
|
||||||
|
const selectedIds: Ref<Set<string>> = ref(new Set())
|
||||||
|
const selectedNodes: Ref<Map<string, NodeRecord>> = ref(new Map())
|
||||||
|
|
||||||
|
const count: ComputedRef<number> = computed(() => selectedIds.value.size)
|
||||||
|
const hasSelection: ComputedRef<boolean> = computed(() => selectedIds.value.size > 0)
|
||||||
|
|
||||||
|
const selectedIdArray: ComputedRef<string[]> = computed(() => Array.from(selectedIds.value))
|
||||||
|
const selectedNodeArray: ComputedRef<NodeRecord[]> = computed(() => Array.from(selectedNodes.value.values()))
|
||||||
|
|
||||||
|
const selectedCollections: ComputedRef<CollectionObject[]> = computed(() =>
|
||||||
|
selectedNodeArray.value.filter((node): node is CollectionObject => node instanceof CollectionObject),
|
||||||
|
)
|
||||||
|
|
||||||
|
const selectedEntities: ComputedRef<EntityObject[]> = computed(() =>
|
||||||
|
selectedNodeArray.value.filter((node): node is EntityObject => node instanceof EntityObject),
|
||||||
|
)
|
||||||
|
|
||||||
|
const isSelected = (nodeId: string): boolean => selectedIds.value.has(nodeId)
|
||||||
|
|
||||||
|
const isTypeAllowed = (node: NodeRecord): boolean => {
|
||||||
|
if (node instanceof CollectionObject && !allowFolders) return false
|
||||||
|
if (node instanceof EntityObject && !allowFiles) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
const select = (node: NodeRecord) => {
|
||||||
|
if (!isTypeAllowed(node)) return
|
||||||
|
|
||||||
|
if (!multiple) {
|
||||||
|
selectedIds.value.clear()
|
||||||
|
selectedNodes.value.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
const nodeId = String(node.identifier)
|
||||||
|
selectedIds.value.add(nodeId)
|
||||||
|
selectedNodes.value.set(nodeId, node)
|
||||||
|
}
|
||||||
|
|
||||||
|
const deselect = (nodeId: string) => {
|
||||||
|
selectedIds.value.delete(nodeId)
|
||||||
|
selectedNodes.value.delete(nodeId)
|
||||||
|
}
|
||||||
|
|
||||||
|
const toggle = (node: NodeRecord) => {
|
||||||
|
const nodeId = String(node.identifier)
|
||||||
|
if (isSelected(nodeId)) {
|
||||||
|
deselect(nodeId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
select(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectMultiple = (nodes: NodeRecord[]) => {
|
||||||
|
if (!multiple) {
|
||||||
|
const lastNode = nodes[nodes.length - 1]
|
||||||
|
if (lastNode && isTypeAllowed(lastNode)) {
|
||||||
|
selectedIds.value.clear()
|
||||||
|
selectedNodes.value.clear()
|
||||||
|
const nodeId = String(lastNode.identifier)
|
||||||
|
selectedIds.value.add(nodeId)
|
||||||
|
selectedNodes.value.set(nodeId, lastNode)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const node of nodes) {
|
||||||
|
if (isTypeAllowed(node)) {
|
||||||
|
const nodeId = String(node.identifier)
|
||||||
|
selectedIds.value.add(nodeId)
|
||||||
|
selectedNodes.value.set(nodeId, node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectAll = (nodes: NodeRecord[]) => {
|
||||||
|
if (!multiple) return
|
||||||
|
selectMultiple(nodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
const clear = () => {
|
||||||
|
selectedIds.value.clear()
|
||||||
|
selectedNodes.value.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
const setSelection = (nodes: NodeRecord[]) => {
|
||||||
|
clear()
|
||||||
|
selectMultiple(nodes)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
selectedIds,
|
||||||
|
selectedNodes,
|
||||||
|
count,
|
||||||
|
hasSelection,
|
||||||
|
selectedIdArray,
|
||||||
|
selectedNodeArray,
|
||||||
|
selectedCollections,
|
||||||
|
selectedEntities,
|
||||||
|
isSelected,
|
||||||
|
select,
|
||||||
|
deselect,
|
||||||
|
toggle,
|
||||||
|
selectMultiple,
|
||||||
|
selectAll,
|
||||||
|
clear,
|
||||||
|
setSelection,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useDocumentSelection
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import type { ModuleIntegrations } from "@KTXC/types/moduleTypes";
|
||||||
|
|
||||||
|
const integrations: ModuleIntegrations = {
|
||||||
|
documents_selector: [
|
||||||
|
{
|
||||||
|
id: 'dialog',
|
||||||
|
label: 'Document Selector Dialog',
|
||||||
|
priority: 10,
|
||||||
|
component: () => import('./components/DocumentSelectorDialog.vue'),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export default integrations;
|
||||||
+8
-2
@@ -2,14 +2,20 @@
|
|||||||
* Documents Manager Module Boot
|
* Documents Manager Module Boot
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import integrations from '@/integrations'
|
||||||
|
|
||||||
console.log('[Documents Manager] Booting module...')
|
console.log('[Documents Manager] Booting module...')
|
||||||
|
|
||||||
console.log('[Documents Manager] Module booted successfully...')
|
console.log('[Documents Manager] Module booted successfully...')
|
||||||
|
|
||||||
// CSS will be injected by build process
|
// CSS filename is injected by the vite plugin at build time
|
||||||
//export const css = ['__CSS_FILENAME_PLACEHOLDER__']
|
export const css = ['__CSS_FILENAME_PLACEHOLDER__']
|
||||||
|
|
||||||
|
export { integrations }
|
||||||
|
|
||||||
// Export services, stores and models for external use
|
// Export services, stores and models for external use
|
||||||
export * from '@/services'
|
export * from '@/services'
|
||||||
export * from '@/stores'
|
export * from '@/stores'
|
||||||
export * from '@/models'
|
export * from '@/models'
|
||||||
|
export * from '@/composables'
|
||||||
|
export * from '@/utils/fileHelpers'
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
import { EntityObject } from '@/models/entity'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the appropriate icon for a file based on its MIME type
|
||||||
|
*/
|
||||||
|
export function getFileIcon(entity: EntityObject): string {
|
||||||
|
const mime = entity.properties.mime || ''
|
||||||
|
if (!mime) return 'mdi-file'
|
||||||
|
if (mime.startsWith('image/')) return 'mdi-file-image'
|
||||||
|
if (mime.startsWith('video/')) return 'mdi-file-video'
|
||||||
|
if (mime.startsWith('audio/')) return 'mdi-file-music'
|
||||||
|
if (mime.startsWith('text/')) return 'mdi-file-document'
|
||||||
|
if (mime === 'application/pdf') return 'mdi-file-pdf-box'
|
||||||
|
if (mime.includes('zip') || mime.includes('tar') || mime.includes('compressed')) return 'mdi-folder-zip'
|
||||||
|
if (mime.includes('word') || mime.includes('document')) return 'mdi-file-word'
|
||||||
|
if (mime.includes('excel') || mime.includes('spreadsheet')) return 'mdi-file-excel'
|
||||||
|
if (mime.includes('powerpoint') || mime.includes('presentation')) return 'mdi-file-powerpoint'
|
||||||
|
return 'mdi-file'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format file size in human readable format
|
||||||
|
*/
|
||||||
|
export function formatSize(bytes: number): string {
|
||||||
|
const safeBytes = Number.isFinite(bytes) ? bytes : 0
|
||||||
|
if (safeBytes === 0) return '0 B'
|
||||||
|
const k = 1024
|
||||||
|
const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
|
||||||
|
const i = Math.floor(Math.log(safeBytes) / Math.log(k))
|
||||||
|
return parseFloat((safeBytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format date string to localized format
|
||||||
|
*/
|
||||||
|
export function formatDate(value: Date | string | null | undefined): string {
|
||||||
|
if (!value) return '—'
|
||||||
|
const date = value instanceof Date ? value : new Date(value)
|
||||||
|
if (Number.isNaN(date.getTime())) return '—'
|
||||||
|
return date.toLocaleDateString('en-US', {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get upload status icon
|
||||||
|
*/
|
||||||
|
export function getUploadStatusIcon(status: string): string {
|
||||||
|
switch (status) {
|
||||||
|
case 'pending': return 'mdi-clock-outline'
|
||||||
|
case 'uploading': return 'mdi-loading mdi-spin'
|
||||||
|
case 'completed': return 'mdi-check-circle'
|
||||||
|
case 'error': return 'mdi-alert-circle'
|
||||||
|
default: return 'mdi-file'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get upload status color
|
||||||
|
*/
|
||||||
|
export function getUploadStatusColor(status: string): string {
|
||||||
|
switch (status) {
|
||||||
|
case 'pending': return 'grey'
|
||||||
|
case 'uploading': return 'primary'
|
||||||
|
case 'completed': return 'success'
|
||||||
|
case 'error': return 'error'
|
||||||
|
default: return 'grey'
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -15,5 +15,5 @@
|
|||||||
"@KTXC/*": ["../../core/src/*"]
|
"@KTXC/*": ["../../core/src/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts", "src/**/*.tsx"]
|
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user