From 64605a341c689ccffd9b284d4035024af010c492 Mon Sep 17 00:00:00 2001 From: Sean Edmunds Date: Tue, 23 Dec 2025 14:55:47 -0600 Subject: [PATCH] Starting guac clients --- package-lock.json | 717 ++++++++---------- package.json | 44 +- src/components/DebouncedInput.tsx | 37 +- src/components/SettingsHeader.tsx | 14 +- src/hooks/useCommonHooks.ts | 2 +- .../homepage/components/Search/Search.tsx | 84 +- .../components/RecommendedApplications.tsx | 2 +- .../components/RecommendedBookmarks.tsx | 2 +- src/pages/settings/Settings.tsx | 12 + .../components/Applications/Applications.tsx | 8 +- .../components/Bookmarks/Bookmarks.tsx | 14 +- .../Bookmarks/DebouncedGroupSettingsItem.tsx | 10 +- .../DebouncedGuacamoleClient.tsx | 122 +++ .../GuacamoleClientSettingsItem.tsx | 23 + .../GuacamoleClients/GuacamoleClients.tsx | 211 ++++++ .../settings/components/Messages/Messages.tsx | 4 +- .../components/Search/SearchHistory.tsx | 2 +- .../components/Search/SearchProviders.tsx | 6 +- .../Theming/ThemePlaylists/ThemePlaylists.tsx | 4 +- .../components/Theming/Themes/Themes.tsx | 4 +- .../settings/components/WoL/WolClients.tsx | 4 +- src/types/guacamoleClient.ts | 6 + src/types/index.ts | 1 + 23 files changed, 853 insertions(+), 480 deletions(-) create mode 100644 src/pages/settings/components/GuacamoleClients/DebouncedGuacamoleClient.tsx create mode 100644 src/pages/settings/components/GuacamoleClients/GuacamoleClientSettingsItem.tsx create mode 100644 src/pages/settings/components/GuacamoleClients/GuacamoleClients.tsx create mode 100644 src/types/guacamoleClient.ts diff --git a/package-lock.json b/package-lock.json index 748477a..454b6c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,37 +8,37 @@ "name": "triggerfrontend", "version": "1.0.0", "dependencies": { - "@gfazioli/mantine-text-animate": "^2.3.4", + "@gfazioli/mantine-text-animate": "^2.3.9", "@hello-pangea/dnd": "^18.0.1", - "@mantine/core": "^8.3.7", - "@mantine/dates": "^8.3.7", - "@mantine/form": "^8.3.7", - "@mantine/hooks": "^8.3.7", - "@mantine/notifications": "^8.3.7", - "@tanstack/react-query": "^5.90.9", - "@tanstack/react-query-devtools": "^5.90.2", - "@tanstack/react-query-persist-client": "^5.90.11", + "@mantine/core": "^8.3.10", + "@mantine/dates": "^8.3.10", + "@mantine/form": "^8.3.10", + "@mantine/hooks": "^8.3.10", + "@mantine/notifications": "^8.3.10", + "@tanstack/react-query": "^5.90.12", + "@tanstack/react-query-devtools": "^5.91.1", + "@tanstack/react-query-persist-client": "^5.90.14", "@tanstack/react-table": "^8.21.3", "idb-keyval": "^6.2.2", - "jotai": "^2.15.1", - "react": "^19.2.0", - "react-dom": "^19.2.0", + "jotai": "^2.16.0", + "react": "^19.2.3", + "react-dom": "^19.2.3", "react-icons": "^5.5.0", - "react-router-dom": "^7.9.6", - "recharts": "^3.4.1" + "react-router-dom": "^7.11.0", + "recharts": "^3.6.0" }, "devDependencies": { - "@types/node": "^24.10.1", - "@types/react": "^19.2.5", + "@types/node": "^25.0.3", + "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^5.1.1", - "@vitest/coverage-v8": "^4.0.9", - "@vitest/ui": "^4.0.9", + "@vitejs/plugin-react": "^5.1.2", + "@vitest/coverage-v8": "^4.0.16", + "@vitest/ui": "^4.0.16", "typescript": "^5.9.3", - "vite": "^7.2.2", + "vite": "^7.3.0", "vite-plugin-dts": "~4.5.4", - "vite-tsconfig-paths": "^5.1.4", - "vitest": "^4.0.9" + "vite-tsconfig-paths": "^6.0.3", + "vitest": "^4.0.16" } }, "node_modules/@babel/code-frame": { @@ -72,7 +72,6 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -314,7 +313,6 @@ "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "devOptional": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", @@ -367,9 +365,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz", - "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", "cpu": [ "ppc64" ], @@ -383,9 +381,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz", - "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", "cpu": [ "arm" ], @@ -399,9 +397,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz", - "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", "cpu": [ "arm64" ], @@ -415,9 +413,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz", - "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", "cpu": [ "x64" ], @@ -431,9 +429,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz", - "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", "cpu": [ "arm64" ], @@ -447,9 +445,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz", - "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", "cpu": [ "x64" ], @@ -463,9 +461,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz", - "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", "cpu": [ "arm64" ], @@ -479,9 +477,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz", - "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", "cpu": [ "x64" ], @@ -495,9 +493,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz", - "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", "cpu": [ "arm" ], @@ -511,9 +509,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz", - "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", "cpu": [ "arm64" ], @@ -527,9 +525,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz", - "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", "cpu": [ "ia32" ], @@ -543,9 +541,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz", - "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", "cpu": [ "loong64" ], @@ -559,9 +557,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz", - "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", "cpu": [ "mips64el" ], @@ -575,9 +573,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz", - "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", "cpu": [ "ppc64" ], @@ -591,9 +589,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz", - "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", "cpu": [ "riscv64" ], @@ -607,9 +605,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz", - "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", "cpu": [ "s390x" ], @@ -623,9 +621,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz", - "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", "cpu": [ "x64" ], @@ -639,9 +637,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz", - "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", "cpu": [ "arm64" ], @@ -655,9 +653,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz", - "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", "cpu": [ "x64" ], @@ -671,9 +669,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz", - "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", "cpu": [ "arm64" ], @@ -687,9 +685,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz", - "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", "cpu": [ "x64" ], @@ -702,10 +700,26 @@ "node": ">=18" } }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz", - "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", "cpu": [ "x64" ], @@ -719,9 +733,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz", - "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", "cpu": [ "arm64" ], @@ -735,9 +749,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz", - "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", "cpu": [ "ia32" ], @@ -751,9 +765,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz", - "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", "cpu": [ "x64" ], @@ -820,10 +834,9 @@ "license": "MIT" }, "node_modules/@gfazioli/mantine-text-animate": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@gfazioli/mantine-text-animate/-/mantine-text-animate-2.3.4.tgz", - "integrity": "sha512-pn12lWpreS29r3EGhZrg6rOcUYprxVIQ7/U6Ake+0rPqZwueGVQy+iXlfWfiXhvpHBJYMSpNSsUHmP6lxpZDuw==", - "license": "MIT", + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@gfazioli/mantine-text-animate/-/mantine-text-animate-2.3.9.tgz", + "integrity": "sha512-9M9+NAWxL65rOWeoZZMtwH/dDlLP4ocZiQoC4EW6OFlhGUqr4LxL3nuZ2WrORW0uTlkUmA85lLLFJD+E4KSzSw==", "peerDependencies": { "@mantine/core": ">=7.0.0", "@mantine/hooks": ">=7.0.0", @@ -898,11 +911,9 @@ } }, "node_modules/@mantine/core": { - "version": "8.3.7", - "resolved": "https://registry.npmjs.org/@mantine/core/-/core-8.3.7.tgz", - "integrity": "sha512-7gUTiUrD0pukpkSNvScGi/e+pBuBWYJP5yFHT4TFf1fmaQAA7PbNoAzUeEkPbVromDtK0VdEcpRlYpDnJhpz2g==", - "license": "MIT", - "peer": true, + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-8.3.10.tgz", + "integrity": "sha512-aKQFETN14v6GtM07b/G5yJneMM1yrgf9mNrTah6GVy5DvQM0AeutITT7toHqh5gxxwzdg/DoY+HQsv5zhqnc5g==", "dependencies": { "@floating-ui/react": "^0.27.16", "clsx": "^2.1.1", @@ -912,32 +923,30 @@ "type-fest": "^4.41.0" }, "peerDependencies": { - "@mantine/hooks": "8.3.7", + "@mantine/hooks": "8.3.10", "react": "^18.x || ^19.x", "react-dom": "^18.x || ^19.x" } }, "node_modules/@mantine/dates": { - "version": "8.3.7", - "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-8.3.7.tgz", - "integrity": "sha512-dyCvkn0aYvvZ8/bUm6EGl9epJ4pq398pzJ/wexzFPHuFdLq/kdIe5zurp/puNcn4CHraglYUflDqj0j8d9aadA==", - "license": "MIT", + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-8.3.10.tgz", + "integrity": "sha512-P1uZ+alYGp7fsmkfd+7Fur4AGrqT0X6BWLiVTomzrbyykA+m4TSwPyQjKfsDc7XRqaqx992br/U65T82zy+qGQ==", "dependencies": { "clsx": "^2.1.1" }, "peerDependencies": { - "@mantine/core": "8.3.7", - "@mantine/hooks": "8.3.7", + "@mantine/core": "8.3.10", + "@mantine/hooks": "8.3.10", "dayjs": ">=1.0.0", "react": "^18.x || ^19.x", "react-dom": "^18.x || ^19.x" } }, "node_modules/@mantine/form": { - "version": "8.3.7", - "resolved": "https://registry.npmjs.org/@mantine/form/-/form-8.3.7.tgz", - "integrity": "sha512-LWC1hlVAfgWtrbCNSoGmo+c8IIXAsLSR2KS25QaIfvRVeMeG1I+RheHK/6VmqKEWChpQzjc346gi4LNApbWRZg==", - "license": "MIT", + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@mantine/form/-/form-8.3.10.tgz", + "integrity": "sha512-TuBmCUIH0qHUig+y9My3bLL9CRoW4g9bijIF6743gqVh0o/daSwplc2TTVMj6sl+F1MR+SJiHtAC8FoR7fdhNw==", "dependencies": { "fast-deep-equal": "^3.1.3", "klona": "^2.0.6" @@ -947,36 +956,32 @@ } }, "node_modules/@mantine/hooks": { - "version": "8.3.7", - "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-8.3.7.tgz", - "integrity": "sha512-2xnKS8C6fTzMoq1dtOJGrh2bIBuWnVrijL/DsDk60UaUgbABh8zScwU5ndX+p02ds2bebo34LovscP9fH38uPg==", - "license": "MIT", - "peer": true, + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-8.3.10.tgz", + "integrity": "sha512-bv+yYHl+keTIvakiDzVJMIjW+o8/Px0G3EdpCMFG+U2ux6SwQqluqoq+/kqrTtT6RaLvQ0fMxjpIULF2cu/xAg==", "peerDependencies": { "react": "^18.x || ^19.x" } }, "node_modules/@mantine/notifications": { - "version": "8.3.7", - "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-8.3.7.tgz", - "integrity": "sha512-NvG9nVfsdoAGbyFxmb/2cCED91N6QVCUsasdcFhpBb5KNMjQbNjwXLVKgvdAA3Fhnjzcc6SF2CdxgTN625kFRA==", - "license": "MIT", + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-8.3.10.tgz", + "integrity": "sha512-0aVpRCyn9u0wuryBnFu1jOwBYw6xGeaNNtTcTUnSvkL6NAypfPon6JG7Wsekf3IuWSTLBjhYaFEIEd4nh7VDpg==", "dependencies": { - "@mantine/store": "8.3.7", + "@mantine/store": "8.3.10", "react-transition-group": "4.4.5" }, "peerDependencies": { - "@mantine/core": "8.3.7", - "@mantine/hooks": "8.3.7", + "@mantine/core": "8.3.10", + "@mantine/hooks": "8.3.10", "react": "^18.x || ^19.x", "react-dom": "^18.x || ^19.x" } }, "node_modules/@mantine/store": { - "version": "8.3.7", - "resolved": "https://registry.npmjs.org/@mantine/store/-/store-8.3.7.tgz", - "integrity": "sha512-YOK+LW7ZVHv1c/bOnStraJbyh7+uRSeo1DG2eH9M+EllXJfNG8bVhOfrnnraYZ1rbbvD/66/hSZkAZJbZeTOAw==", - "license": "MIT", + "version": "8.3.10", + "resolved": "https://registry.npmjs.org/@mantine/store/-/store-8.3.10.tgz", + "integrity": "sha512-38t1UivcucZo9hQq27F/eqR5GvovNs4NHEz6DchOuZzV5IJWqO8+T07ivb8wct47ovYe42rPfLcaOdnIEvMsJA==", "peerDependencies": { "react": "^18.x || ^19.x" } @@ -1132,8 +1137,7 @@ "version": "1.0.0-next.29", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@reduxjs/toolkit": { "version": "2.8.2", @@ -1162,11 +1166,10 @@ } }, "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.47.tgz", - "integrity": "sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw==", - "dev": true, - "license": "MIT" + "version": "1.0.0-beta.53", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz", + "integrity": "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==", + "dev": true }, "node_modules/@rollup/pluginutils": { "version": "5.1.4", @@ -1605,32 +1608,29 @@ "license": "MIT" }, "node_modules/@tanstack/query-core": { - "version": "5.90.9", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.9.tgz", - "integrity": "sha512-UFOCQzi6pRGeVTVlPNwNdnAvT35zugcIydqjvFUzG62dvz2iVjElmNp/hJkUoM5eqbUPfSU/GJIr/wbvD8bTUw==", - "license": "MIT", + "version": "5.90.12", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.12.tgz", + "integrity": "sha512-T1/8t5DhV/SisWjDnaiU2drl6ySvsHj1bHBCWNXd+/T+Hh1cf6JodyEYMd5sgwm+b/mETT4EV3H+zCVczCU5hg==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@tanstack/query-devtools": { - "version": "5.90.1", - "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.90.1.tgz", - "integrity": "sha512-GtINOPjPUH0OegJExZ70UahT9ykmAhmtNVcmtdnOZbxLwT7R5OmRztR5Ahe3/Cu7LArEmR6/588tAycuaWb1xQ==", - "license": "MIT", + "version": "5.91.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-devtools/-/query-devtools-5.91.1.tgz", + "integrity": "sha512-l8bxjk6BMsCaVQH6NzQEE/bEgFy1hAs5qbgXl0xhzezlaQbPk6Mgz9BqEg2vTLPOHD8N4k+w/gdgCbEzecGyNg==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@tanstack/query-persist-client-core": { - "version": "5.91.8", - "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.91.8.tgz", - "integrity": "sha512-aee4w+piU37e9Xe3VIoyE/T1ovKPJurRPTgZrNLnP8ExIM6EgmfLgDIYIdz69EUgVlaXOIwJH70dX2wo/TgKTQ==", - "license": "MIT", + "version": "5.91.11", + "resolved": "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-5.91.11.tgz", + "integrity": "sha512-NNpRGxQY/nVOdzfs5QbevPjGsUVoEiFwqxxaopLyu6todwtDOCfIOfhXSmpMVXBiCxUn7kqaUB1iwaBKqoAVRQ==", "dependencies": { - "@tanstack/query-core": "5.90.9" + "@tanstack/query-core": "5.90.12" }, "funding": { "type": "github", @@ -1638,13 +1638,11 @@ } }, "node_modules/@tanstack/react-query": { - "version": "5.90.9", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.9.tgz", - "integrity": "sha512-Zke2AaXiaSfnG8jqPZR52m8SsclKT2d9//AgE/QIzyNvbpj/Q2ln+FsZjb1j69bJZUouBvX2tg9PHirkTm8arw==", - "license": "MIT", - "peer": true, + "version": "5.90.12", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.12.tgz", + "integrity": "sha512-graRZspg7EoEaw0a8faiUASCyJrqjKPdqJ9EwuDRUF9mEYJ1YPczI9H+/agJ0mOJkPCJDk0lsz5QTrLZ/jQ2rg==", "dependencies": { - "@tanstack/query-core": "5.90.9" + "@tanstack/query-core": "5.90.12" }, "funding": { "type": "github", @@ -1655,36 +1653,34 @@ } }, "node_modules/@tanstack/react-query-devtools": { - "version": "5.90.2", - "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.90.2.tgz", - "integrity": "sha512-vAXJzZuBXtCQtrY3F/yUNJCV4obT/A/n81kb3+YqLbro5Z2+phdAbceO+deU3ywPw8B42oyJlp4FhO0SoivDFQ==", - "license": "MIT", + "version": "5.91.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-5.91.1.tgz", + "integrity": "sha512-tRnJYwEbH0kAOuToy8Ew7bJw1lX3AjkkgSlf/vzb+NpnqmHPdWM+lA2DSdGQSLi1SU0PDRrrCI1vnZnci96CsQ==", "dependencies": { - "@tanstack/query-devtools": "5.90.1" + "@tanstack/query-devtools": "5.91.1" }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "@tanstack/react-query": "^5.90.2", + "@tanstack/react-query": "^5.90.10", "react": "^18 || ^19" } }, "node_modules/@tanstack/react-query-persist-client": { - "version": "5.90.11", - "resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.90.11.tgz", - "integrity": "sha512-AI4QWvzuxNG8akMTxvVyYY61NqfA45PCmyiER0pNyuHH5l/3TwudSzN00I25kjMcu9ZpD8OIlYfsmg36L8Olwg==", - "license": "MIT", + "version": "5.90.14", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-persist-client/-/react-query-persist-client-5.90.14.tgz", + "integrity": "sha512-jTGnr/DBlzV/UYqU+b8bZWECBuqh3Q3g7Ih50IktZkvmwTUsidQhhl2JyknNYVZkl5AgMfPAywNKZLTI82wmlA==", "dependencies": { - "@tanstack/query-persist-client-core": "5.91.8" + "@tanstack/query-persist-client-core": "5.91.11" }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "@tanstack/react-query": "^5.90.9", + "@tanstack/react-query": "^5.90.12", "react": "^18 || ^19" } }, @@ -1773,7 +1769,6 @@ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, - "license": "MIT", "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" @@ -1846,8 +1841,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/@types/estree": { "version": "1.0.8", @@ -1857,25 +1851,21 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", - "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "version": "25.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", + "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", "dev": true, - "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } }, "node_modules/@types/react": { - "version": "19.2.5", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.5.tgz", - "integrity": "sha512-keKxkZMqnDicuvFoJbzrhbtdLSPhj/rZThDlKWCDbgXmUg0rEUFtRssDXKYmtXluZlIqiC5VqkCgRwzuyLHKHw==", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", + "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", "devOptional": true, - "license": "MIT", - "peer": true, "dependencies": { - "csstype": "^3.0.2" + "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { @@ -1895,16 +1885,15 @@ "license": "MIT" }, "node_modules/@vitejs/plugin-react": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.1.tgz", - "integrity": "sha512-WQfkSw0QbQ5aJ2CHYw23ZGkqnRwqKHD/KYsMeTkZzPT4Jcf0DcBxBtwMJxnu6E7oxw5+JC6ZAiePgh28uJ1HBA==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.2.tgz", + "integrity": "sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ==", "dev": true, - "license": "MIT", "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.47", + "@rolldown/pluginutils": "1.0.0-beta.53", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, @@ -1916,21 +1905,20 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.9.tgz", - "integrity": "sha512-70oyhP+Q0HlWBIeGSP74YBw5KSjYhNgSCQjvmuQFciMqnyF36WL2cIkcT7XD85G4JPmBQitEMUsx+XMFv2AzQA==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.16.tgz", + "integrity": "sha512-2rNdjEIsPRzsdu6/9Eq0AYAzYdpP6Bx9cje9tL3FE5XzXRQF1fNU9pe/1yE8fCrS0HD+fBtt6gLPh6LI57tX7A==", "dev": true, - "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.0.9", + "@vitest/utils": "4.0.16", "ast-v8-to-istanbul": "^0.3.8", - "debug": "^4.4.3", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", "istanbul-lib-source-maps": "^5.0.6", "istanbul-reports": "^3.2.0", "magicast": "^0.5.1", + "obug": "^2.1.1", "std-env": "^3.10.0", "tinyrainbow": "^3.0.3" }, @@ -1938,8 +1926,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "4.0.9", - "vitest": "4.0.9" + "@vitest/browser": "4.0.16", + "vitest": "4.0.16" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -1948,17 +1936,16 @@ } }, "node_modules/@vitest/expect": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.9.tgz", - "integrity": "sha512-C2vyXf5/Jfj1vl4DQYxjib3jzyuswMi/KHHVN2z+H4v16hdJ7jMZ0OGe3uOVIt6LyJsAofDdaJNIFEpQcrSTFw==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.16.tgz", + "integrity": "sha512-eshqULT2It7McaJkQGLkPjPjNph+uevROGuIMJdG3V+0BSR2w9u6J9Lwu+E8cK5TETlfou8GRijhafIMhXsimA==", "dev": true, - "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.0.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.0.9", - "@vitest/utils": "4.0.9", - "chai": "^6.2.0", + "@vitest/spy": "4.0.16", + "@vitest/utils": "4.0.16", + "chai": "^6.2.1", "tinyrainbow": "^3.0.3" }, "funding": { @@ -1966,13 +1953,12 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.9.tgz", - "integrity": "sha512-PUyaowQFHW+9FKb4dsvvBM4o025rWMlEDXdWRxIOilGaHREYTi5Q2Rt9VCgXgPy/hHZu1LeuXtrA/GdzOatP2g==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.16.tgz", + "integrity": "sha512-yb6k4AZxJTB+q9ycAvsoxGn+j/po0UaPgajllBgt1PzoMAAmJGYFdDk0uCcRcxb3BrME34I6u8gHZTQlkqSZpg==", "dev": true, - "license": "MIT", "dependencies": { - "@vitest/spy": "4.0.9", + "@vitest/spy": "4.0.16", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -1997,17 +1983,15 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, - "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } }, "node_modules/@vitest/pretty-format": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.9.tgz", - "integrity": "sha512-Hor0IBTwEi/uZqB7pvGepyElaM8J75pYjrrqbC8ZYMB9/4n5QA63KC15xhT+sqHpdGWfdnPo96E8lQUxs2YzSQ==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.16.tgz", + "integrity": "sha512-eNCYNsSty9xJKi/UdVD8Ou16alu7AYiS2fCPRs0b1OdhJiV89buAXQLpTbe+X8V9L6qrs9CqyvU7OaAopJYPsA==", "dev": true, - "license": "MIT", "dependencies": { "tinyrainbow": "^3.0.3" }, @@ -2016,13 +2000,12 @@ } }, "node_modules/@vitest/runner": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.9.tgz", - "integrity": "sha512-aF77tsXdEvIJRkj9uJZnHtovsVIx22Ambft9HudC+XuG/on1NY/bf5dlDti1N35eJT+QZLb4RF/5dTIG18s98w==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.16.tgz", + "integrity": "sha512-VWEDm5Wv9xEo80ctjORcTQRJ539EGPB3Pb9ApvVRAY1U/WkHXmmYISqU5E79uCwcW7xYUV38gwZD+RV755fu3Q==", "dev": true, - "license": "MIT", "dependencies": { - "@vitest/utils": "4.0.9", + "@vitest/utils": "4.0.16", "pathe": "^2.0.3" }, "funding": { @@ -2030,13 +2013,12 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.9.tgz", - "integrity": "sha512-r1qR4oYstPbnOjg0Vgd3E8ADJbi4ditCzqr+Z9foUrRhIy778BleNyZMeAJ2EjV+r4ASAaDsdciC9ryMy8xMMg==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.16.tgz", + "integrity": "sha512-sf6NcrYhYBsSYefxnry+DR8n3UV4xWZwWxYbCJUt2YdvtqzSPR7VfGrY0zsv090DAbjFZsi7ZaMi1KnSRyK1XA==", "dev": true, - "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.9", + "@vitest/pretty-format": "4.0.16", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -2045,24 +2027,21 @@ } }, "node_modules/@vitest/spy": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.9.tgz", - "integrity": "sha512-J9Ttsq0hDXmxmT8CUOWUr1cqqAj2FJRGTdyEjSR+NjoOGKEqkEWj+09yC0HhI8t1W6t4Ctqawl1onHgipJve1A==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.16.tgz", + "integrity": "sha512-4jIOWjKP0ZUaEmJm00E0cOBLU+5WE0BpeNr3XN6TEF05ltro6NJqHWxXD0kA8/Zc8Nh23AT8WQxwNG+WeROupw==", "dev": true, - "license": "MIT", "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/ui": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-4.0.9.tgz", - "integrity": "sha512-6HV2HHl9aRJ09TlYj/WAQxaa797Ezb5u0LpgabthlASAUAWKgw/W1DSPX7t848mMZmIUvzZgnUHGIylAoYHP0w==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-4.0.16.tgz", + "integrity": "sha512-rkoPH+RqWopVxDnCBE/ysIdfQ2A7j1eDmW8tCxxrR9nnFBa9jKf86VgsSAzxBd1x+ny0GC4JgiD3SNfRHv3pOg==", "dev": true, - "license": "MIT", - "peer": true, "dependencies": { - "@vitest/utils": "4.0.9", + "@vitest/utils": "4.0.16", "fflate": "^0.8.2", "flatted": "^3.3.3", "pathe": "^2.0.3", @@ -2074,17 +2053,16 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "vitest": "4.0.9" + "vitest": "4.0.16" } }, "node_modules/@vitest/utils": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.9.tgz", - "integrity": "sha512-cEol6ygTzY4rUPvNZM19sDf7zGa35IYTm9wfzkHoT/f5jX10IOY7QleWSOh5T0e3I3WVozwK5Asom79qW8DiuQ==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.16.tgz", + "integrity": "sha512-h8z9yYhV3e1LEfaQ3zdypIrnAg/9hguReGZoS7Gl0aBG5xgA410zBqECqmaF/+RkTggRsfnzc1XaAHA6bmUufA==", "dev": true, - "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.9", + "@vitest/pretty-format": "4.0.16", "tinyrainbow": "^3.0.3" }, "funding": { @@ -2198,7 +2176,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -2252,7 +2229,6 @@ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, - "license": "MIT", "engines": { "node": ">=12" } @@ -2321,7 +2297,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001718", "electron-to-chromium": "^1.5.160", @@ -2357,11 +2332,10 @@ "license": "CC-BY-4.0" }, "node_modules/chai": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.1.tgz", - "integrity": "sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" } @@ -2400,12 +2374,15 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", - "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", - "license": "MIT", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", "engines": { "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/css-box-model": { @@ -2418,9 +2395,9 @@ } }, "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==" }, "node_modules/d3-array": { "version": "3.2.4", @@ -2618,8 +2595,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/es-toolkit": { "version": "1.39.5", @@ -2632,9 +2608,9 @@ ] }, "node_modules/esbuild": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", - "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", "dev": true, "hasInstallScript": true, "bin": { @@ -2644,31 +2620,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.1", - "@esbuild/android-arm": "0.25.1", - "@esbuild/android-arm64": "0.25.1", - "@esbuild/android-x64": "0.25.1", - "@esbuild/darwin-arm64": "0.25.1", - "@esbuild/darwin-x64": "0.25.1", - "@esbuild/freebsd-arm64": "0.25.1", - "@esbuild/freebsd-x64": "0.25.1", - "@esbuild/linux-arm": "0.25.1", - "@esbuild/linux-arm64": "0.25.1", - "@esbuild/linux-ia32": "0.25.1", - "@esbuild/linux-loong64": "0.25.1", - "@esbuild/linux-mips64el": "0.25.1", - "@esbuild/linux-ppc64": "0.25.1", - "@esbuild/linux-riscv64": "0.25.1", - "@esbuild/linux-s390x": "0.25.1", - "@esbuild/linux-x64": "0.25.1", - "@esbuild/netbsd-arm64": "0.25.1", - "@esbuild/netbsd-x64": "0.25.1", - "@esbuild/openbsd-arm64": "0.25.1", - "@esbuild/openbsd-x64": "0.25.1", - "@esbuild/sunos-x64": "0.25.1", - "@esbuild/win32-arm64": "0.25.1", - "@esbuild/win32-ia32": "0.25.1", - "@esbuild/win32-x64": "0.25.1" + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" } }, "node_modules/escalade": { @@ -2694,11 +2671,10 @@ "license": "MIT" }, "node_modules/expect-type": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", - "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=12.0.0" } @@ -2752,15 +2728,13 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/flatted": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/fs-extra": { "version": "11.3.0", @@ -2988,10 +2962,9 @@ "dev": true }, "node_modules/jotai": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.15.1.tgz", - "integrity": "sha512-yHT1HAZ3ba2Q8wgaUQ+xfBzEtcS8ie687I8XVCBinfg4bNniyqLIN+utPXWKQE93LMF5fPbQSVRZqgpcN5yd6Q==", - "license": "MIT", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/jotai/-/jotai-2.16.0.tgz", + "integrity": "sha512-NmkwPBet0SHQ28GBfEb10sqnbVOYyn6DL4iazZgGRDUKxSWL0iqcm+IK4TqTSFC2ixGk+XX2e46Wbv364a3cKg==", "engines": { "node": ">=12.20.0" }, @@ -3212,7 +3185,6 @@ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" } @@ -3263,6 +3235,16 @@ "node": ">=0.10.0" } }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ] + }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", @@ -3382,26 +3364,22 @@ "license": "MIT" }, "node_modules/react": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", - "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", - "license": "MIT", - "peer": true, + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", + "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", - "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", - "license": "MIT", - "peer": true, + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.0" + "react": "^19.2.3" } }, "node_modules/react-icons": { @@ -3415,8 +3393,7 @@ "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "peer": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-number-format": { "version": "5.4.4", @@ -3509,10 +3486,9 @@ } }, "node_modules/react-router": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.6.tgz", - "integrity": "sha512-Y1tUp8clYRXpfPITyuifmSoE2vncSME18uVLgaqyxh9H35JWpIfzHo+9y3Fzh5odk/jxPW29IgLgzcdwxGqyNA==", - "license": "MIT", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.11.0.tgz", + "integrity": "sha512-uI4JkMmjbWCZc01WVP2cH7ZfSzH91JAZUDd7/nIprDgWxBV1TkkmLToFh7EbMTcMak8URFRa2YoBL/W8GWnCTQ==", "dependencies": { "cookie": "^1.0.1", "set-cookie-parser": "^2.6.0" @@ -3531,12 +3507,11 @@ } }, "node_modules/react-router-dom": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.6.tgz", - "integrity": "sha512-2MkC2XSXq6HjGcihnx1s0DBWQETI4mlis4Ux7YTLvP67xnGxCvq+BcCQSO81qQHVUTM1V53tl4iVVaY5sReCOA==", - "license": "MIT", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.11.0.tgz", + "integrity": "sha512-e49Ir/kMGRzFOOrYQBdoitq3ULigw4lKbAyKusnvtDu2t4dBX4AGYPrzNvorXmVuOyeakai6FUPW5MmibvVG8g==", "dependencies": { - "react-router": "7.9.6" + "react-router": "7.11.0" }, "engines": { "node": ">=20.0.0" @@ -3601,13 +3576,9 @@ } }, "node_modules/recharts": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.4.1.tgz", - "integrity": "sha512-35kYg6JoOgwq8sE4rhYkVWwa6aAIgOtT+Ob0gitnShjwUwZmhrmy7Jco/5kJNF4PnLXgt9Hwq+geEMS+WrjU1g==", - "license": "MIT", - "workspaces": [ - "www" - ], + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.6.0.tgz", + "integrity": "sha512-L5bjxvQRAe26RlToBAziKUB7whaGKEwD3znoM6fz3DrTowCIC/FnJYnuq1GEzB8Zv2kdTfaxQfi5GoH0tBinyg==", "dependencies": { "@reduxjs/toolkit": "1.x.x || 2.x.x", "clsx": "^2.1.1", @@ -3634,8 +3605,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/redux-thunk": { "version": "3.1.0", @@ -3692,7 +3662,6 @@ "integrity": "sha512-iasGAQoZ5dWDzULEUX3jiW0oB1qyFOepSyDyoU6S/OhVlDIwj5knI5QBa5RRQ0sK7OE0v+8VIi2JuV+G+3tfNg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -3749,22 +3718,19 @@ "node_modules/set-cookie-parser": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", - "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", - "license": "MIT" + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==" }, "node_modules/siginfo": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" + "dev": true }, "node_modules/sirv": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.2.tgz", "integrity": "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==", "dev": true, - "license": "MIT", "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", @@ -3793,15 +3759,13 @@ "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/std-env": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/string-argv": { "version": "0.3.2", @@ -3866,15 +3830,16 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", "dev": true, - "license": "MIT" + "engines": { + "node": ">=18" + } }, "node_modules/tinyglobby": { "version": "0.2.15", @@ -3898,7 +3863,6 @@ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", "dev": true, - "license": "MIT", "engines": { "node": ">=14.0.0" } @@ -3908,7 +3872,6 @@ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -3957,7 +3920,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -4148,14 +4110,12 @@ } }, "node_modules/vite": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.2.tgz", - "integrity": "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", + "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", "dev": true, - "license": "MIT", - "peer": true, "dependencies": { - "esbuild": "^0.25.0", + "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", @@ -4251,9 +4211,9 @@ } }, "node_modules/vite-tsconfig-paths": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.1.4.tgz", - "integrity": "sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-6.0.3.tgz", + "integrity": "sha512-7bL7FPX/DSviaZGYUKowWF1AiDVWjMjxNbE8lyaVGDezkedWqfGhlnQ4BZXre0ZN5P4kAgIJfAlgFDVyjrCIyg==", "dev": true, "dependencies": { "debug": "^4.1.1", @@ -4270,29 +4230,27 @@ } }, "node_modules/vitest": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.9.tgz", - "integrity": "sha512-E0Ja2AX4th+CG33yAFRC+d1wFx2pzU5r6HtG6LiPSE04flaE0qB6YyjSw9ZcpJAtVPfsvZGtJlKWZpuW7EHRxg==", + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.16.tgz", + "integrity": "sha512-E4t7DJ9pESL6E3I8nFjPa4xGUd3PmiWDLsDztS2qXSJWfHtbQnwAWylaBvSNY48I3vr8PTqIZlyK8TE3V3CA4Q==", "dev": true, - "license": "MIT", - "peer": true, "dependencies": { - "@vitest/expect": "4.0.9", - "@vitest/mocker": "4.0.9", - "@vitest/pretty-format": "4.0.9", - "@vitest/runner": "4.0.9", - "@vitest/snapshot": "4.0.9", - "@vitest/spy": "4.0.9", - "@vitest/utils": "4.0.9", - "debug": "^4.4.3", + "@vitest/expect": "4.0.16", + "@vitest/mocker": "4.0.16", + "@vitest/pretty-format": "4.0.16", + "@vitest/runner": "4.0.16", + "@vitest/snapshot": "4.0.16", + "@vitest/spy": "4.0.16", + "@vitest/utils": "4.0.16", "es-module-lexer": "^1.7.0", "expect-type": "^1.2.2", "magic-string": "^0.30.21", + "obug": "^2.1.1", "pathe": "^2.0.3", "picomatch": "^4.0.3", "std-env": "^3.10.0", "tinybench": "^2.9.0", - "tinyexec": "^0.3.2", + "tinyexec": "^1.0.2", "tinyglobby": "^0.2.15", "tinyrainbow": "^3.0.3", "vite": "^6.0.0 || ^7.0.0", @@ -4309,12 +4267,12 @@ }, "peerDependencies": { "@edge-runtime/vm": "*", - "@types/debug": "^4.1.12", + "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.0.9", - "@vitest/browser-preview": "4.0.9", - "@vitest/browser-webdriverio": "4.0.9", - "@vitest/ui": "4.0.9", + "@vitest/browser-playwright": "4.0.16", + "@vitest/browser-preview": "4.0.16", + "@vitest/browser-webdriverio": "4.0.16", + "@vitest/ui": "4.0.16", "happy-dom": "*", "jsdom": "*" }, @@ -4322,7 +4280,7 @@ "@edge-runtime/vm": { "optional": true }, - "@types/debug": { + "@opentelemetry/api": { "optional": true }, "@types/node": { @@ -4359,7 +4317,6 @@ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, - "license": "MIT", "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" diff --git a/package.json b/package.json index 47a7982..6607cd6 100644 --- a/package.json +++ b/package.json @@ -10,36 +10,36 @@ "preview": "vite preview" }, "dependencies": { - "@gfazioli/mantine-text-animate": "^2.3.4", + "@gfazioli/mantine-text-animate": "^2.3.9", "@hello-pangea/dnd": "^18.0.1", - "@mantine/core": "^8.3.7", - "@mantine/dates": "^8.3.7", - "@mantine/form": "^8.3.7", - "@mantine/hooks": "^8.3.7", - "@mantine/notifications": "^8.3.7", - "@tanstack/react-query": "^5.90.9", - "@tanstack/react-query-devtools": "^5.90.2", - "@tanstack/react-query-persist-client": "^5.90.11", + "@mantine/core": "^8.3.10", + "@mantine/dates": "^8.3.10", + "@mantine/form": "^8.3.10", + "@mantine/hooks": "^8.3.10", + "@mantine/notifications": "^8.3.10", + "@tanstack/react-query": "^5.90.12", + "@tanstack/react-query-devtools": "^5.91.1", + "@tanstack/react-query-persist-client": "^5.90.14", "@tanstack/react-table": "^8.21.3", "idb-keyval": "^6.2.2", - "jotai": "^2.15.1", - "react": "^19.2.0", - "react-dom": "^19.2.0", + "jotai": "^2.16.0", + "react": "^19.2.3", + "react-dom": "^19.2.3", "react-icons": "^5.5.0", - "react-router-dom": "^7.9.6", - "recharts": "^3.4.1" + "react-router-dom": "^7.11.0", + "recharts": "^3.6.0" }, "devDependencies": { - "@types/node": "^24.10.1", - "@types/react": "^19.2.5", + "@types/node": "^25.0.3", + "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", - "@vitejs/plugin-react": "^5.1.1", - "@vitest/coverage-v8": "^4.0.9", - "@vitest/ui": "^4.0.9", + "@vitejs/plugin-react": "^5.1.2", + "@vitest/coverage-v8": "^4.0.16", + "@vitest/ui": "^4.0.16", "typescript": "^5.9.3", - "vite": "^7.2.2", + "vite": "^7.3.0", "vite-plugin-dts": "~4.5.4", - "vite-tsconfig-paths": "^5.1.4", - "vitest": "^4.0.9" + "vite-tsconfig-paths": "^6.0.3", + "vitest": "^4.0.16" } } diff --git a/src/components/DebouncedInput.tsx b/src/components/DebouncedInput.tsx index 8136082..8f130fc 100644 --- a/src/components/DebouncedInput.tsx +++ b/src/components/DebouncedInput.tsx @@ -1,7 +1,5 @@ -import { ActionIcon, TextInput } from '@mantine/core'; +import { TextInput, type TextInputProps } from '@mantine/core'; import { useEffect, useState } from 'react'; -import { FiX } from 'react-icons/fi'; -import { textInputClasses } from 'styles'; export function DebouncedInput({ value: initialValue, @@ -12,7 +10,7 @@ export function DebouncedInput({ value: string | number; onChange: (value: string | number) => void; debounce?: number; -} & Omit, 'onChange'>) { +} & Omit) { const [value, setValue] = useState(initialValue); useEffect(() => { @@ -25,43 +23,14 @@ export function DebouncedInput({ }, debounce); return () => clearTimeout(timeout); - }, [value, debounce, onChange]); + }, [value]); return ( e.stopPropagation()} onChange={(e) => setValue(e.target.value)} - classNames={textInputClasses} - styles={{ - input: { - borderRadius: 0, - borderStyle: 'none', - color: 'var(--mantine-color-primary-0)', - '&::placeholder': { - color: 'red !important', - }, - }, - wrapper: { - '&::placeholder': { - color: 'red !important', - }, - }, - }} - rightSection={ - value && ( - { - setValue(''); - }} - > - - - ) - } /> ); } diff --git a/src/components/SettingsHeader.tsx b/src/components/SettingsHeader.tsx index ee7405d..a396b15 100644 --- a/src/components/SettingsHeader.tsx +++ b/src/components/SettingsHeader.tsx @@ -7,7 +7,6 @@ import { Stack, Switch, Text, - TextInput, } from '@mantine/core'; import { useCommonHooks } from 'hooks'; import { useState } from 'react'; @@ -20,6 +19,7 @@ import { textClasses, textInputClasses, } from 'styles'; +import { DebouncedInput } from './DebouncedInput'; export function SettingsHeader({ setDragging, @@ -40,8 +40,8 @@ export function SettingsHeader({ highlightList: string[]; description: string; }; - searchValue: string | undefined; - setSearchValue: (searchValue: string) => void; + searchValue: string | number; + setSearchValue: (searchValue: string | number) => void; searchPlaceholder: string | undefined; isLoading: boolean; setIsLoading: (isLoading: boolean) => void; @@ -120,7 +120,7 @@ export function SettingsHeader({ )} {searchValue !== undefined && ( - { - setIsLoading(true); - setSearchValue(event.target.value); + onInput={() => setIsLoading(true)} + onChange={(value: any) => { + setSearchValue(value); }} style={{ zIndex: 100, diff --git a/src/hooks/useCommonHooks.ts b/src/hooks/useCommonHooks.ts index 245f947..e36efd9 100644 --- a/src/hooks/useCommonHooks.ts +++ b/src/hooks/useCommonHooks.ts @@ -69,7 +69,7 @@ export function useCommonHooks() { key: 'providerIcon', defaultValue: 'FaGoogle', }); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState(''); const [providerLabel, setProviderLabel] = useState(defaultProviderLabel); const [providerURL, setProviderURL] = useState(defaultProviderURL); const [providerPrefix, setProviderPrefix] = useState(defaultProviderPrefix); diff --git a/src/pages/homepage/components/Search/Search.tsx b/src/pages/homepage/components/Search/Search.tsx index 0172430..35d52ec 100644 --- a/src/pages/homepage/components/Search/Search.tsx +++ b/src/pages/homepage/components/Search/Search.tsx @@ -20,6 +20,7 @@ import type { Bookmark, CurrentWeather, ExtendedForecast, + GuacamoleClient, Provider, SearchHistoryItem, } from 'types'; @@ -48,9 +49,14 @@ export default function Search({ endpoint: 'api/providers', }); const [providers, setProviders] = useState([]); + const [guacamoleClients, setGuacamoleClients] = useState([]); const { data: applicationData, isFetching: isApplicationDataFetching } = useQueryAPI({ endpoint: 'api/enabledApplications', }); + const { data: guacamoleClientData, isFetched: guacamoleClientDataIsFetched } = + useQueryAPI({ + endpoint: 'api/guacamoleClients', + }); const { data: bookmarkData, isFetched: bookmarksIsFetched } = useQueryAPI({ endpoint: 'api/bookmarks', }); @@ -130,10 +136,6 @@ export default function Search({ item.target.value.substr(1, item.target.value.indexOf(' ') - 1) ?? item.target.value.substr(1); subtext = item.target.value.substr(2 + option.length); - } else if (item.target.value.startsWith('!')) { - if (item.target.value.startsWith('!w')) { - subtext = item.target.value.substr(2); - } } else { subtext = item.target.value; } @@ -162,6 +164,13 @@ export default function Search({ ? url : `http://${url}`; open(validUrl, '_self'); + } else if (providerLabel.startsWith('Connect to')) { + const id = guacamoleClients.find( + (client: GuacamoleClient) => + client.clientName.substring(1).toLowerCase() === item.target.value.substr(1), + )?.id; + + open(`https://sean.bet/guacamole/#/${id}`, '_self'); } else if (urlPattern.test(item.target.value)) { if (/^(https?:\/\/).*/i.test(item.target.value)) globalThis.location = item.target.value; @@ -250,7 +259,6 @@ export default function Search({ } } }; - const onInput = (item: any) => { openDropdown(); setSearchValue(item.currentTarget.value); @@ -288,6 +296,17 @@ export default function Search({ } else { setProviderLabel('Invalid function'); } + } else if (item.target.value.startsWith('>')) { + if ( + guacamoleClients?.find( + (client: GuacamoleClient) => + client.clientName.substring(1).toLowerCase() === item.target.value.substr(1), + ) + ) { + setProviderLabel(`Connect to ${item.target.value.substr(1)}`); + } else { + setProviderLabel('Invalid connection'); + } } else { setProviderLabel(defaultProviderLabel); setProviderURL(defaultProviderURL); @@ -311,6 +330,21 @@ export default function Search({ }; }); } + if (splittedSearch[0].startsWith('>')) { + return guacamoleClientData + .filter((guacamoleClient: GuacamoleClient) => + guacamoleClient.clientName + .toLowerCase() + .includes(splittedSearch[0].substring(1).toLowerCase()), + ) + .map((guacamoleClient: GuacamoleClient) => { + return { + label: guacamoleClient.clientName, + value: guacamoleClient.clientIdentifier, + ...guacamoleClient, + }; + }); + } const historyOptions = options .filter((option: any) => { return splittedSearch.every((searchWord) => @@ -350,7 +384,9 @@ export default function Search({ : (providers.find((p: Provider) => p.prefix === item.option.prefix)?.icon ?? '') ]; - return searchValue.startsWith('!') ? ( + if ((searchValue as string).startsWith('>')) { + } + return (searchValue as string).startsWith('!') ? ( + ) : (searchValue as string).startsWith('>') ? ( + { + e.preventDefault(); + e.stopPropagation(); + }} + > + + Connect to + + + {item.option.name || item.option.clientName || 'Invalid connection'} + + ) : item.option.value === 'load' ? ( { + if (guacamoleClientData && guacamoleClientDataIsFetched) { + setGuacamoleClients(guacamoleClientData); + } + }, [guacamoleClientData, guacamoleClientDataIsFetched]); + useEffect(() => { if (applicationData && !isApplicationDataFetching) { setApplications(applicationData); @@ -429,7 +491,7 @@ export default function Search({ if (applications) { setFilteredApplications( applications.filter((app: Application) => - app.name.toLowerCase().includes(searchValue.toLowerCase()), + app.name.toLowerCase().includes((searchValue as string).toLowerCase()), ), ); } @@ -441,7 +503,7 @@ export default function Search({ bookmarkData.filter( (bookmark: Bookmark) => bookmark.enabled === 1 && - bookmark.name.toLowerCase().includes(searchValue.toLowerCase()), + bookmark.name.toLowerCase().includes((searchValue as string).toLowerCase()), ), ); } @@ -467,7 +529,7 @@ export default function Search({ }, [listIndex, dropdownOpened]); useEffect(() => { - const splittedSearch = searchValue.toLowerCase().trim().split(' '); + const splittedSearch = (searchValue as string).toLowerCase().trim().split(' '); const filtered = searchHistory.filter((item: SearchHistoryItem) => { const option = `${item.prefix} ${item.searchTerm}`; const words = option.toLowerCase().trim().split(' '); @@ -514,8 +576,8 @@ export default function Search({ ...item, }))} filter={optionsFilter} - value={searchValue} - searchValue={searchValue} + value={searchValue as string} + searchValue={searchValue as string} placeholder={placeholderValue} nothingFoundMessage={ Nothing found... diff --git a/src/pages/homepage/components/Search/components/RecommendedApplications.tsx b/src/pages/homepage/components/Search/components/RecommendedApplications.tsx index 90697c1..6bb36cb 100644 --- a/src/pages/homepage/components/Search/components/RecommendedApplications.tsx +++ b/src/pages/homepage/components/Search/components/RecommendedApplications.tsx @@ -7,7 +7,7 @@ export default function RecommendedApplications({ dropdownOpened, filteredApplications, }: { - searchValue: string; + searchValue: string | number; dropdownOpened: boolean; filteredApplications: Application[]; }) { diff --git a/src/pages/homepage/components/Search/components/RecommendedBookmarks.tsx b/src/pages/homepage/components/Search/components/RecommendedBookmarks.tsx index 4f33b70..65d3409 100644 --- a/src/pages/homepage/components/Search/components/RecommendedBookmarks.tsx +++ b/src/pages/homepage/components/Search/components/RecommendedBookmarks.tsx @@ -7,7 +7,7 @@ export default function RecommendedBookmarks({ dropdownOpened, }: { bookmarks: Bookmark[]; - searchValue: string; + searchValue: string | number; dropdownOpened: boolean; }) { return ( diff --git a/src/pages/settings/Settings.tsx b/src/pages/settings/Settings.tsx index db0be9d..c5c8ded 100644 --- a/src/pages/settings/Settings.tsx +++ b/src/pages/settings/Settings.tsx @@ -14,6 +14,7 @@ import { useNavigate, useParams } from 'react-router-dom'; import { actionIconClasses, scrollAreaClasses, tabClasses, textClasses } from 'styles'; import Applications from './components/Applications/Applications'; import Bookmarks from './components/Bookmarks/Bookmarks'; +import GuacamoleClients from './components/GuacamoleClients/GuacamoleClients'; import Messages from './components/Messages/Messages'; import Personalization from './components/Personalization/Personalization'; import SearchHistory from './components/Search/SearchHistory'; @@ -162,6 +163,9 @@ export function Settings() { {isMobile ? : 'WoL Clients'} + + {isMobile ? : 'Guacamole Clients'} + + + + + + ); diff --git a/src/pages/settings/components/Applications/Applications.tsx b/src/pages/settings/components/Applications/Applications.tsx index 2af02af..ca81225 100644 --- a/src/pages/settings/components/Applications/Applications.tsx +++ b/src/pages/settings/components/Applications/Applications.tsx @@ -60,7 +60,7 @@ const ApplicationSettings = () => { const [applicationList, setApplicationList] = useState([]); const { isMobile, reorder, theme } = useCommonHooks(); const { mutateAsync } = useMutationAPI(); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState(''); const [debouncedSearch] = useDebouncedValue(searchValue, 500); const [dragging, setDragging] = useState(false); const [isOpen, setIsOpen] = useState(false); @@ -98,9 +98,9 @@ const ApplicationSettings = () => { applicationData .filter( (a: Application) => - a.name.toLowerCase().includes(debouncedSearch.toLowerCase()) || - a.url.toLowerCase().includes(debouncedSearch.toLowerCase()) || - a.baseUrl.toLowerCase().includes(debouncedSearch.toLowerCase()), + a.name.toLowerCase().includes((debouncedSearch as string).toLowerCase()) || + a.url.toLowerCase().includes((debouncedSearch as string).toLowerCase()) || + a.baseUrl.toLowerCase().includes((debouncedSearch as string).toLowerCase()), ) .sort((a: Application, b: Application) => (a.index > b.index ? 1 : -1)), ); diff --git a/src/pages/settings/components/Bookmarks/Bookmarks.tsx b/src/pages/settings/components/Bookmarks/Bookmarks.tsx index ef4cbe8..5007993 100644 --- a/src/pages/settings/components/Bookmarks/Bookmarks.tsx +++ b/src/pages/settings/components/Bookmarks/Bookmarks.tsx @@ -50,7 +50,7 @@ const BookmarkSettings = () => { const [groupList, setGroupList] = useState([]); const { isMobile, reorder, theme } = useCommonHooks(); const { mutateAsync } = useMutationAPI(); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState(''); const [debouncedGroupSearch] = useDebouncedValue(searchValue, 500); const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false); const [isLoading, setIsLoading] = useState(false); @@ -93,8 +93,12 @@ const BookmarkSettings = () => { bookmarks .filter( (a: Bookmark) => - a.name.toLowerCase().includes(debouncedGroupSearch.toLowerCase()) || - a.url.toLowerCase().includes(debouncedGroupSearch.toLowerCase()), + a.name + .toLowerCase() + .includes((debouncedGroupSearch as string).toLowerCase()) || + a.url + .toLowerCase() + .includes((debouncedGroupSearch as string).toLowerCase()), ) .map((a: Bookmark) => groupData.find( @@ -105,7 +109,9 @@ const BookmarkSettings = () => { ), ]; const foundGroups = groupData.filter((a: BookmarkGroup) => - a.categoryName.toLowerCase().includes(debouncedGroupSearch.toLowerCase()), + a.categoryName + .toLowerCase() + .includes((debouncedGroupSearch as string).toLowerCase()), ); const groupList = [...new Set([...foundBookmarkGroups, ...foundGroups])].sort( diff --git a/src/pages/settings/components/Bookmarks/DebouncedGroupSettingsItem.tsx b/src/pages/settings/components/Bookmarks/DebouncedGroupSettingsItem.tsx index e8dcda2..2899a00 100644 --- a/src/pages/settings/components/Bookmarks/DebouncedGroupSettingsItem.tsx +++ b/src/pages/settings/components/Bookmarks/DebouncedGroupSettingsItem.tsx @@ -41,7 +41,7 @@ function DebouncedGroupSettingsItem({ }: { bookmarkGroup: BookmarkGroup; bookmarks: Bookmark[]; - searchTerm: string; + searchTerm: string | number; }) { const { isMobile, handleDelete, reorder, theme } = useCommonHooks(); const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false); @@ -262,8 +262,12 @@ function DebouncedGroupSettingsItem({ > - {(bookmark.name.toLowerCase().includes(searchTerm) || - bookmark.url.toLowerCase().includes(searchTerm)) && + {(bookmark.name + .toLowerCase() + .includes(searchTerm as string) || + bookmark.url + .toLowerCase() + .includes(searchTerm as string)) && searchTerm && ( void; +}) { + const { handleDelete, isMobile, theme } = useCommonHooks(); + const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false); + const { mutateAsync } = useMutationAPI(); + + const [client, setClient] = useState(guacamoleClient); + const [update, setUpdate] = useState({}); + const [debounced] = useDebouncedValue(update, 1000); + const handleClose = () => { + setIsOpen(false); + closeModal(); + }; + + useEffect(() => { + if (Object.keys(debounced).length) { + mutateAsync({ method: 'PATCH', endpoint: 'api/guacamoleClients', body: debounced }); + } + }, [debounced]); + + useEffect(() => { + if (update !== client && Object.keys(update).length) { + setClient(update); + } + }, [update]); + return ( + + handleDelete(client, 'api/guacamoleClients')} + title={'Delete Guacamole Client'} + body={ + + Are you sure you want to delete this WoL Client? + {`"${client.clientName}"`} + This action cannot be undone! + + } + /> + + { + openModal(); + }} + > + + + + + { + setUpdate({ + ...client, + clientName: event.target.value, + }); + }} + styles={ + theme.textShadowsEnabled + ? { + label: { boxShadow: '2px 2px var(--mantine-color-border-0)' }, + } + : undefined + } + /> + { + setUpdate({ + ...client, + clientIdentifier: event.target.value, + }); + }} + styles={ + theme.textShadowsEnabled + ? { + label: { boxShadow: '2px 2px var(--mantine-color-border-0)' }, + } + : undefined + } + /> + + + ); +} + +export default DebouncedGuacamoleClient; diff --git a/src/pages/settings/components/GuacamoleClients/GuacamoleClientSettingsItem.tsx b/src/pages/settings/components/GuacamoleClients/GuacamoleClientSettingsItem.tsx new file mode 100644 index 0000000..1de1e56 --- /dev/null +++ b/src/pages/settings/components/GuacamoleClients/GuacamoleClientSettingsItem.tsx @@ -0,0 +1,23 @@ +import { Card, Stack, Text } from '@mantine/core'; +import { FaLaptop } from 'react-icons/fa'; +import { cardClasses } from 'styles'; +import type { GuacamoleClient } from 'types'; + +function GuacamoleClientSettingsItem({ client }: { client: GuacamoleClient }) { + return ( + + + + {client.clientName} + {client.clientIdentifier} + + + ); +} + +export default GuacamoleClientSettingsItem; diff --git a/src/pages/settings/components/GuacamoleClients/GuacamoleClients.tsx b/src/pages/settings/components/GuacamoleClients/GuacamoleClients.tsx new file mode 100644 index 0000000..cffdfb6 --- /dev/null +++ b/src/pages/settings/components/GuacamoleClients/GuacamoleClients.tsx @@ -0,0 +1,211 @@ +import { + Button, + Grid, + GridCol, + Group, + LoadingOverlay, + Popover, + Stack, + TextInput, +} from '@mantine/core'; +import { isNotEmpty, useForm } from '@mantine/form'; +import { useDebouncedValue, useDisclosure } from '@mantine/hooks'; +import { AddItemModal, NoItemsFound, SettingsHeader } from 'components'; +import { useCommonHooks, useMutationAPI, useQueryAPI } from 'hooks'; +import { useEffect, useState } from 'react'; +import { popoverClasses, textInputClasses } from 'styles'; +import type { GuacamoleClient } from 'types'; +import DebouncedGuacamoleClient from './DebouncedGuacamoleClient'; +import GuacamoleClientSettingsItem from './GuacamoleClientSettingsItem'; + +const GuacamoleClients = () => { + const defaultGuacamoleClient: GuacamoleClient = { + id: undefined, + clientName: '', + clientIdentifier: '', + enabled: 1, + }; + const form = useForm({ + initialValues: defaultGuacamoleClient, + validate: { + clientName: isNotEmpty('Client Name is required'), + clientIdentifier: isNotEmpty('Client Identifier is required'), + }, + }); + const endpoint = 'api/guacamoleClients'; + const { + data: guacamoleClientsData, + isFetched: guacamoleClientsIsFetched, + isFetching: guacamoleClientsIsFetching, + } = useQueryAPI({ + endpoint: endpoint, + }); + const [guacamoleClients, setGuacamoleClients] = useState([]); + const { mutateAsync } = useMutationAPI(); + const { isMobile, theme } = useCommonHooks(); + const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false); + const [searchValue, setSearchValue] = useState(''); + const [debouncedSearch] = useDebouncedValue(searchValue, 500); + const [isOpen, setIsOpen] = useState(false); + const [isLoading, setIsLoading] = useState(false); + + const handleClose = () => { + closeModal(); + form.reset(); + }; + + useEffect(() => { + if (guacamoleClientsData && guacamoleClientsIsFetched) { + setGuacamoleClients( + guacamoleClientsData.filter((a: GuacamoleClient) => + a.clientName.toLowerCase().includes((debouncedSearch as string).toLowerCase()), + ), + ); + } + if (debouncedSearch === searchValue) { + setIsLoading(false); + } + }, [guacamoleClientsData, guacamoleClientsIsFetched, debouncedSearch]); + + return ( + + { + mutateAsync({ + method: 'POST', + endpoint: endpoint, + body: { ...values, enabled: 1 }, + }); + handleClose(); + })} + > + + + + + + + + + + + + } + /> + + + + + {guacamoleClients.length > 0 ? ( + guacamoleClients?.map((client: GuacamoleClient) => ( + + + + + + + + + + + + + )) + ) : ( + + + + )} + + + + ); +}; +export default GuacamoleClients; diff --git a/src/pages/settings/components/Messages/Messages.tsx b/src/pages/settings/components/Messages/Messages.tsx index d4b8e69..f06f7fc 100644 --- a/src/pages/settings/components/Messages/Messages.tsx +++ b/src/pages/settings/components/Messages/Messages.tsx @@ -38,7 +38,7 @@ const MessageSettings = () => { const [messages, setMessages] = useState([]); const [message, setMessage] = useState({}); const [debounced] = useDebouncedValue(message, 1000); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState(''); const [debouncedSearch] = useDebouncedValue(searchValue, 500); const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false); const [isLoading, setIsLoading] = useState(false); @@ -52,7 +52,7 @@ const MessageSettings = () => { if (messageData && messageDataIsFetched) { setMessages( messageData.filter((m: Message) => - m.message.toLowerCase().includes(debouncedSearch.toLowerCase()), + m.message.toLowerCase().includes((debouncedSearch as string).toLowerCase()), ), ); } diff --git a/src/pages/settings/components/Search/SearchHistory.tsx b/src/pages/settings/components/Search/SearchHistory.tsx index 0994872..b634d1e 100644 --- a/src/pages/settings/components/Search/SearchHistory.tsx +++ b/src/pages/settings/components/Search/SearchHistory.tsx @@ -17,7 +17,7 @@ const SearchHistory = () => { endpoint: searchEndpoint, }); const [searchHistory, setSearchHistory] = useState([]); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState(''); const [searchHistoryItem, setSearchHistoryItem] = useState(); const [debouncedSearch] = useDebouncedValue(searchValue, 500); const [isLoading, setIsLoading] = useState(false); diff --git a/src/pages/settings/components/Search/SearchProviders.tsx b/src/pages/settings/components/Search/SearchProviders.tsx index e79a389..212f02f 100644 --- a/src/pages/settings/components/Search/SearchProviders.tsx +++ b/src/pages/settings/components/Search/SearchProviders.tsx @@ -63,7 +63,7 @@ const SearchProviderSettings = () => { const { isMobile, theme, iconFilter } = useCommonHooks(); const { mutateAsync } = useMutationAPI(); const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState(''); const [debouncedSearch] = useDebouncedValue(searchValue, 500); const [isOpen, setIsOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); @@ -79,8 +79,8 @@ const SearchProviderSettings = () => { providerData .filter( (a: Provider) => - a.name.toLowerCase().includes(debouncedSearch.toLowerCase()) || - a.url.toLowerCase().includes(debouncedSearch.toLowerCase()), + a.name.toLowerCase().includes((debouncedSearch as string).toLowerCase()) || + a.url.toLowerCase().includes((debouncedSearch as string).toLowerCase()), ) .sort((a: Provider, b: Provider) => (a.prefix > b.prefix ? 1 : -1)), ); diff --git a/src/pages/settings/components/Theming/ThemePlaylists/ThemePlaylists.tsx b/src/pages/settings/components/Theming/ThemePlaylists/ThemePlaylists.tsx index ceffed0..d1636bd 100644 --- a/src/pages/settings/components/Theming/ThemePlaylists/ThemePlaylists.tsx +++ b/src/pages/settings/components/Theming/ThemePlaylists/ThemePlaylists.tsx @@ -34,7 +34,7 @@ export function ThemePlaylists() { const [selectedPlaylist, setSelectedPlaylist] = useState(defaultPlaylist); const { currentThemePlaylist, theme, isMobile } = useCommonHooks(); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState(''); const [debouncedSearch] = useDebouncedValue(searchValue, 500); const [isLoading, setIsLoading] = useState(false); @@ -62,7 +62,7 @@ export function ThemePlaylists() { setThemePlaylists( themePlaylistData.filter( (a: ThemePlaylist) => - a.name.toLowerCase().includes(debouncedSearch.toLowerCase()) || + a.name.toLowerCase().includes((debouncedSearch as string).toLowerCase()) || a.name.includes('Time of Day'), ), ); diff --git a/src/pages/settings/components/Theming/Themes/Themes.tsx b/src/pages/settings/components/Theming/Themes/Themes.tsx index 3dff111..9ee91c2 100644 --- a/src/pages/settings/components/Theming/Themes/Themes.tsx +++ b/src/pages/settings/components/Theming/Themes/Themes.tsx @@ -65,7 +65,7 @@ export function Themes() { textShadowsEnabled: 0, appShadowsEnabled: 0, }); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState(''); const [debouncedSearch] = useDebouncedValue(searchValue, 500); const [isLoading, setIsLoading] = useState(false); const [isNew, setIsNew] = useState(false); @@ -103,7 +103,7 @@ export function Themes() { if (allThemeData && allThemeDataIsFetched) { setAllThemes( allThemeData.filter((a: Theme) => - a.name.toLowerCase().includes(debouncedSearch.toLowerCase()), + a.name.toLowerCase().includes((debouncedSearch as string).toLowerCase()), ), ); } diff --git a/src/pages/settings/components/WoL/WolClients.tsx b/src/pages/settings/components/WoL/WolClients.tsx index f3d894c..b55ad92 100644 --- a/src/pages/settings/components/WoL/WolClients.tsx +++ b/src/pages/settings/components/WoL/WolClients.tsx @@ -46,7 +46,7 @@ const WolClientSettings = () => { const { mutateAsync } = useMutationAPI(); const { isMobile, theme } = useCommonHooks(); const [modalOpened, { open: openModal, close: closeModal }] = useDisclosure(false); - const [searchValue, setSearchValue] = useState(''); + const [searchValue, setSearchValue] = useState(''); const [debouncedSearch] = useDebouncedValue(searchValue, 500); const [isOpen, setIsOpen] = useState(false); const [isLoading, setIsLoading] = useState(false); @@ -60,7 +60,7 @@ const WolClientSettings = () => { if (wolClientsData && wolClientsIsFetched) { setWolClients( wolClientsData.filter((a: WolClient) => - a.hostname.toLowerCase().includes(debouncedSearch.toLowerCase()), + a.hostname.toLowerCase().includes((debouncedSearch as string).toLowerCase()), ), ); } diff --git a/src/types/guacamoleClient.ts b/src/types/guacamoleClient.ts new file mode 100644 index 0000000..7f5aa2c --- /dev/null +++ b/src/types/guacamoleClient.ts @@ -0,0 +1,6 @@ +export interface GuacamoleClient { + id: number | undefined; + clientName: string; + clientIdentifier: string; + enabled: number; +} diff --git a/src/types/index.ts b/src/types/index.ts index f7b86c4..b94f9c0 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,6 +1,7 @@ export type { AppCategory, Application } from './application'; export type { Bookmark } from './bookmark'; export type { BookmarkGroup } from './bookmarkGroup'; +export type { GuacamoleClient } from './guacamoleClient'; export type { Location } from './location'; export type { Message } from './message'; export type { PersonalData } from './personalData';