diff --git a/frontend/web/package.json b/frontend/web/package.json index 74f9165..5f32d89 100644 --- a/frontend/web/package.json +++ b/frontend/web/package.json @@ -13,11 +13,11 @@ "@emotion/styled": "^11.11.0", "@mui/joy": "5.0.0-beta.14", "@reduxjs/toolkit": "^1.9.7", - "axios": "^1.6.0", + "axios": "^1.6.2", "classnames": "^2.3.2", "copy-to-clipboard": "^3.3.3", "dayjs": "^1.11.10", - "i18next": "^23.6.0", + "i18next": "^23.7.6", "lodash-es": "^4.17.21", "lucide-react": "^0.292.0", "nice-grpc-web": "^3.3.2", @@ -25,24 +25,23 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-hot-toast": "^2.4.1", - "react-i18next": "^13.3.1", - "react-redux": "^8.1.3", - "react-router-dom": "^6.18.0", + "react-i18next": "^13.5.0", + "react-router-dom": "^6.19.0", "react-use": "^17.4.0", "tailwindcss": "^3.3.5", "zustand": "^4.4.6" }, "devDependencies": { - "@bufbuild/buf": "^1.27.2", - "@trivago/prettier-plugin-sort-imports": "^4.2.1", + "@bufbuild/buf": "^1.28.1", + "@trivago/prettier-plugin-sort-imports": "^4.3.0", "@types/lodash-es": "^4.17.11", - "@types/react": "^18.2.37", - "@types/react-dom": "^18.2.15", - "@typescript-eslint/eslint-plugin": "^6.10.0", - "@typescript-eslint/parser": "^6.10.0", - "@vitejs/plugin-react-swc": "^3.4.1", + "@types/react": "^18.2.38", + "@types/react-dom": "^18.2.16", + "@typescript-eslint/eslint-plugin": "^6.12.0", + "@typescript-eslint/parser": "^6.12.0", + "@vitejs/plugin-react-swc": "^3.5.0", "autoprefixer": "^10.4.16", - "eslint": "^8.53.0", + "eslint": "^8.54.0", "eslint-config-prettier": "^8.10.0", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.33.2", @@ -50,7 +49,7 @@ "postcss": "^8.4.31", "prettier": "2.6.2", "protobufjs": "^7.2.5", - "typescript": "^5.2.2", + "typescript": "^5.3.2", "vite": "^4.5.0" } } diff --git a/frontend/web/pnpm-lock.yaml b/frontend/web/pnpm-lock.yaml index 4a138a8..4b5b56f 100644 --- a/frontend/web/pnpm-lock.yaml +++ b/frontend/web/pnpm-lock.yaml @@ -7,19 +7,19 @@ settings: dependencies: '@emotion/react': specifier: ^11.11.1 - version: 11.11.1(@types/react@18.2.37)(react@18.2.0) + version: 11.11.1(@types/react@18.2.38)(react@18.2.0) '@emotion/styled': specifier: ^11.11.0 - version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.37)(react@18.2.0) + version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.38)(react@18.2.0) '@mui/joy': specifier: 5.0.0-beta.14 - version: 5.0.0-beta.14(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) + version: 5.0.0-beta.14(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.38)(react-dom@18.2.0)(react@18.2.0) '@reduxjs/toolkit': specifier: ^1.9.7 - version: 1.9.7(react-redux@8.1.3)(react@18.2.0) + version: 1.9.7(react@18.2.0) axios: - specifier: ^1.6.0 - version: 1.6.0 + specifier: ^1.6.2 + version: 1.6.2 classnames: specifier: ^2.3.2 version: 2.3.2 @@ -30,8 +30,8 @@ dependencies: specifier: ^1.11.10 version: 1.11.10 i18next: - specifier: ^23.6.0 - version: 23.6.0 + specifier: ^23.7.6 + version: 23.7.6 lodash-es: specifier: ^4.17.21 version: 4.17.21 @@ -54,14 +54,11 @@ dependencies: specifier: ^2.4.1 version: 2.4.1(csstype@3.1.2)(react-dom@18.2.0)(react@18.2.0) react-i18next: - specifier: ^13.3.1 - version: 13.3.1(i18next@23.6.0)(react-dom@18.2.0)(react@18.2.0) - react-redux: - specifier: ^8.1.3 - version: 8.1.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) + specifier: ^13.5.0 + version: 13.5.0(i18next@23.7.6)(react-dom@18.2.0)(react@18.2.0) react-router-dom: - specifier: ^6.18.0 - version: 6.18.0(react-dom@18.2.0)(react@18.2.0) + specifier: ^6.19.0 + version: 6.19.0(react-dom@18.2.0)(react@18.2.0) react-use: specifier: ^17.4.0 version: 17.4.0(react-dom@18.2.0)(react@18.2.0) @@ -70,48 +67,48 @@ dependencies: version: 3.3.5 zustand: specifier: ^4.4.6 - version: 4.4.6(@types/react@18.2.37)(react@18.2.0) + version: 4.4.6(@types/react@18.2.38)(react@18.2.0) devDependencies: '@bufbuild/buf': - specifier: ^1.27.2 - version: 1.27.2 + specifier: ^1.28.1 + version: 1.28.1 '@trivago/prettier-plugin-sort-imports': - specifier: ^4.2.1 - version: 4.2.1(prettier@2.6.2) + specifier: ^4.3.0 + version: 4.3.0(prettier@2.6.2) '@types/lodash-es': specifier: ^4.17.11 version: 4.17.11 '@types/react': - specifier: ^18.2.37 - version: 18.2.37 + specifier: ^18.2.38 + version: 18.2.38 '@types/react-dom': - specifier: ^18.2.15 - version: 18.2.15 + specifier: ^18.2.16 + version: 18.2.16 '@typescript-eslint/eslint-plugin': - specifier: ^6.10.0 - version: 6.10.0(@typescript-eslint/parser@6.10.0)(eslint@8.53.0)(typescript@5.2.2) + specifier: ^6.12.0 + version: 6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.3.2) '@typescript-eslint/parser': - specifier: ^6.10.0 - version: 6.10.0(eslint@8.53.0)(typescript@5.2.2) + specifier: ^6.12.0 + version: 6.12.0(eslint@8.54.0)(typescript@5.3.2) '@vitejs/plugin-react-swc': - specifier: ^3.4.1 - version: 3.4.1(vite@4.5.0) + specifier: ^3.5.0 + version: 3.5.0(vite@4.5.0) autoprefixer: specifier: ^10.4.16 version: 10.4.16(postcss@8.4.31) eslint: - specifier: ^8.53.0 - version: 8.53.0 + specifier: ^8.54.0 + version: 8.54.0 eslint-config-prettier: specifier: ^8.10.0 - version: 8.10.0(eslint@8.53.0) + version: 8.10.0(eslint@8.54.0) eslint-plugin-prettier: specifier: ^4.2.1 - version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.53.0)(prettier@2.6.2) + version: 4.2.1(eslint-config-prettier@8.10.0)(eslint@8.54.0)(prettier@2.6.2) eslint-plugin-react: specifier: ^7.33.2 - version: 7.33.2(eslint@8.53.0) + version: 7.33.2(eslint@8.54.0) long: specifier: ^5.2.3 version: 5.2.3 @@ -125,8 +122,8 @@ devDependencies: specifier: ^7.2.5 version: 7.2.5 typescript: - specifier: ^5.2.2 - version: 5.2.2 + specifier: ^5.3.2 + version: 5.3.2 vite: specifier: ^4.5.0 version: 4.5.0 @@ -143,11 +140,11 @@ packages: engines: {node: '>=10'} dev: false - /@babel/code-frame@7.22.13: - resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} + /@babel/code-frame@7.23.4: + resolution: {integrity: sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/highlight': 7.22.20 + '@babel/highlight': 7.23.4 chalk: 2.4.2 /@babel/generator@7.17.7: @@ -159,11 +156,11 @@ packages: source-map: 0.5.7 dev: true - /@babel/generator@7.23.3: - resolution: {integrity: sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==} + /@babel/generator@7.23.4: + resolution: {integrity: sha512-esuS49Cga3HcThFNebGhlgsrVLkvhqvYDTzgjfFFlHJcIfLe5jFmRRfCQ1KuBfc4Jrtn3ndLgKWAKjBE+IraYQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.3 + '@babel/types': 7.23.4 '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.20 jsesc: 2.5.2 @@ -179,56 +176,56 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.22.15 - '@babel/types': 7.23.3 + '@babel/types': 7.23.4 dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.3 + '@babel/types': 7.23.4 dev: true /@babel/helper-module-imports@7.22.15: resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.3 + '@babel/types': 7.23.4 dev: false /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.3 + '@babel/types': 7.23.4 dev: true - /@babel/helper-string-parser@7.22.5: - resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + /@babel/helper-string-parser@7.23.4: + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} engines: {node: '>=6.9.0'} /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} - /@babel/highlight@7.22.20: - resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} + /@babel/highlight@7.23.4: + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 - /@babel/parser@7.23.3: - resolution: {integrity: sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==} + /@babel/parser@7.23.4: + resolution: {integrity: sha512-vf3Xna6UEprW+7t6EtOmFpHNAuxw3xqPZghy+brsnusscJRW5BMUzzHZc5ICjULee81WeUV2jjakG09MDglJXQ==} engines: {node: '>=6.0.0'} hasBin: true dependencies: '@babel/types': 7.17.0 dev: true - /@babel/runtime@7.23.2: - resolution: {integrity: sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==} + /@babel/runtime@7.23.4: + resolution: {integrity: sha512-2Yv65nlWnWlSpe3fXEyX5i7fx5kIKo4Qbcj+hMO0odwaneFjfXw5fdum+4yL20O0QiaHpia0cYQ9xpNMqrBwHg==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.0 @@ -238,23 +235,23 @@ packages: resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.13 - '@babel/parser': 7.23.3 - '@babel/types': 7.23.3 + '@babel/code-frame': 7.23.4 + '@babel/parser': 7.23.4 + '@babel/types': 7.23.4 dev: true /@babel/traverse@7.23.2: resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.13 - '@babel/generator': 7.23.3 + '@babel/code-frame': 7.23.4 + '@babel/generator': 7.23.4 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.3 - '@babel/types': 7.23.3 + '@babel/parser': 7.23.4 + '@babel/types': 7.23.4 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: @@ -269,16 +266,16 @@ packages: to-fast-properties: 2.0.0 dev: true - /@babel/types@7.23.3: - resolution: {integrity: sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==} + /@babel/types@7.23.4: + resolution: {integrity: sha512-7uIFwVYpoplT5jp/kVv6EF93VaJ8H+Yn5IczYiaAi98ajzjfoZfslet/e0sLh+wVBjb2qqIut1b0S26VSafsSQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-string-parser': 7.22.5 + '@babel/helper-string-parser': 7.23.4 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 - /@bufbuild/buf-darwin-arm64@1.27.2: - resolution: {integrity: sha512-ob1IAhFVsAVUr5o4EAwoeQ6FOGJdiS6eYGTGQiZzJEAYSs2dX/WQ9+Xz9EPQUb93n7PMjNs38DLDfwGQ3u3dsg==} + /@bufbuild/buf-darwin-arm64@1.28.1: + resolution: {integrity: sha512-nAyvwKkcd8qQTExCZo5MtSRhXLK7e3vzKFKHjXfkveRakSUST2HFlFZAHfErZimN4wBrPTN0V0hNRU8PPjkMpQ==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -286,8 +283,8 @@ packages: dev: true optional: true - /@bufbuild/buf-darwin-x64@1.27.2: - resolution: {integrity: sha512-Kp0HBvLjeOxJtZ/j3vOulX6G3u5pa9vksVmJ5HGjhL0BZJwavh8Bd9YgrBDrTzKtTQMHxmhTSaNEgNUWkjecfw==} + /@bufbuild/buf-darwin-x64@1.28.1: + resolution: {integrity: sha512-b0eT3xd3vX5a5lWAbo5h7FPuf9MsOJI4I39qs4TZnrlZ8BOuPfqzwzijiFf9UCwaX2vR1NQXexIoQ80Ci+fCHw==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -295,8 +292,8 @@ packages: dev: true optional: true - /@bufbuild/buf-linux-aarch64@1.27.2: - resolution: {integrity: sha512-rq+bpT+FMR1iiUvcHno1SPS4e0Ydr+F7ArIzN5cO4DKL09sBJXcaVGa7fRRlBZvNJTt3XRVtlE8LNLGH7zjBOg==} + /@bufbuild/buf-linux-aarch64@1.28.1: + resolution: {integrity: sha512-p5h9bZCVLMh8No9/7k7ulXzsFx5P7Lu6DiUMjSJ6aBXPMYo6Xl7r/6L2cQkpsZ53HMtIxCgMYS9a7zoS4K8wIw==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -304,8 +301,8 @@ packages: dev: true optional: true - /@bufbuild/buf-linux-x64@1.27.2: - resolution: {integrity: sha512-t/lcJ06gELy+4hVROuoeX8Y+oXq9NrPX+UgT5WujGo21oOb8UAQETZLRefj2U4IRqYqXhTKicfOI2y8xI7CSlQ==} + /@bufbuild/buf-linux-x64@1.28.1: + resolution: {integrity: sha512-fVJ3DiRigIso06jgEl+JNp59Y5t2pxDHd10d3SA4r+14sXbZ2J7Gy/wBqVXPry4x/jW567KKlvmhg7M5ZBgCQQ==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -313,8 +310,8 @@ packages: dev: true optional: true - /@bufbuild/buf-win32-arm64@1.27.2: - resolution: {integrity: sha512-rJieGmtSw4tfteW6mhjdtDDTFBbl2HBan1FnfNAOZH4ZrTwfcOO5Vn3fUMl+jPtiCpTscyzVaYHI+LvYffSdvg==} + /@bufbuild/buf-win32-arm64@1.28.1: + resolution: {integrity: sha512-KJiRJpugQRK/jXC46Xjlb68UydWhCZj2jHdWLIwNtgXd1WTJ3LngChZV7Y6pPK08pwBAVz0JYeVbD5IlTCD4TQ==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -322,8 +319,8 @@ packages: dev: true optional: true - /@bufbuild/buf-win32-x64@1.27.2: - resolution: {integrity: sha512-x9IKCHgj6GmDGH2xlTo80l2feNU3hUeoEwLFLH4I5Qs2L1gfYIDMZGp+0Bhm5eK9CIWYtkJqeqGRIJkrJA6CfQ==} + /@bufbuild/buf-win32-x64@1.28.1: + resolution: {integrity: sha512-vMnc+7OVCkmlRWQsgYHgUqiBPRIjD8XeoRyApJ07YZzGs7DkRH4LhvmacJbLd3wORylbn6gLz3pQa8J/M61mzg==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -331,25 +328,25 @@ packages: dev: true optional: true - /@bufbuild/buf@1.27.2: - resolution: {integrity: sha512-hwZYF0DCxvmTAZIAeT/q66HYtIxnSH9jn/CVElaJA/l+Clr9zhLdfKFd1yD2lMqHpNUEeXtA8T0ABXv29NVfYQ==} + /@bufbuild/buf@1.28.1: + resolution: {integrity: sha512-WRDagrf0uBjfV9s5eyrSPJDcdI4A5Q7JMCA4aMrHRR8fo/TTjniDBjJprszhaguqsDkn/LS4QIu92HVFZCrl9A==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@bufbuild/buf-darwin-arm64': 1.27.2 - '@bufbuild/buf-darwin-x64': 1.27.2 - '@bufbuild/buf-linux-aarch64': 1.27.2 - '@bufbuild/buf-linux-x64': 1.27.2 - '@bufbuild/buf-win32-arm64': 1.27.2 - '@bufbuild/buf-win32-x64': 1.27.2 + '@bufbuild/buf-darwin-arm64': 1.28.1 + '@bufbuild/buf-darwin-x64': 1.28.1 + '@bufbuild/buf-linux-aarch64': 1.28.1 + '@bufbuild/buf-linux-x64': 1.28.1 + '@bufbuild/buf-win32-arm64': 1.28.1 + '@bufbuild/buf-win32-x64': 1.28.1 dev: true /@emotion/babel-plugin@11.11.0: resolution: {integrity: sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==} dependencies: '@babel/helper-module-imports': 7.22.15 - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.4 '@emotion/hash': 0.9.1 '@emotion/memoize': 0.8.1 '@emotion/serialize': 1.1.2 @@ -385,7 +382,7 @@ packages: resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} dev: false - /@emotion/react@11.11.1(@types/react@18.2.37)(react@18.2.0): + /@emotion/react@11.11.1(@types/react@18.2.38)(react@18.2.0): resolution: {integrity: sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==} peerDependencies: '@types/react': '*' @@ -394,14 +391,14 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.4 '@emotion/babel-plugin': 11.11.0 '@emotion/cache': 11.11.0 '@emotion/serialize': 1.1.2 '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 '@emotion/weak-memoize': 0.3.1 - '@types/react': 18.2.37 + '@types/react': 18.2.38 hoist-non-react-statics: 3.3.2 react: 18.2.0 dev: false @@ -420,7 +417,7 @@ packages: resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} dev: false - /@emotion/styled@11.11.0(@emotion/react@11.11.1)(@types/react@18.2.37)(react@18.2.0): + /@emotion/styled@11.11.0(@emotion/react@11.11.1)(@types/react@18.2.38)(react@18.2.0): resolution: {integrity: sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==} peerDependencies: '@emotion/react': ^11.0.0-rc.0 @@ -430,14 +427,14 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.4 '@emotion/babel-plugin': 11.11.0 '@emotion/is-prop-valid': 1.2.1 - '@emotion/react': 11.11.1(@types/react@18.2.37)(react@18.2.0) + '@emotion/react': 11.11.1(@types/react@18.2.38)(react@18.2.0) '@emotion/serialize': 1.1.2 '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 - '@types/react': 18.2.37 + '@types/react': 18.2.38 react: 18.2.0 dev: false @@ -659,13 +656,13 @@ packages: dev: true optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.53.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.54.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.53.0 + eslint: 8.54.0 eslint-visitor-keys: 3.4.3 dev: true @@ -682,7 +679,7 @@ packages: debug: 4.3.4 espree: 9.6.1 globals: 13.23.0 - ignore: 5.2.4 + ignore: 5.3.0 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -691,8 +688,8 @@ packages: - supports-color dev: true - /@eslint/js@8.53.0: - resolution: {integrity: sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==} + /@eslint/js@8.54.0: + resolution: {integrity: sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true @@ -709,8 +706,8 @@ packages: '@floating-ui/utils': 0.1.6 dev: false - /@floating-ui/react-dom@2.0.3(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-wOoKUw2P24/OXbNr3bbCqWgoltsyY7lFBDPVtjj/V4WDIJ5hja2C/r+CoWmS+Y75Ahndds3wa7eJRhnJxTCJaQ==} + /@floating-ui/react-dom@2.0.4(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' @@ -769,7 +766,7 @@ packages: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 - /@mui/base@5.0.0-beta.23(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0): + /@mui/base@5.0.0-beta.23(@types/react@18.2.38)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-9L8SQUGAWtd/Qi7Qem26+oSSgpY7f2iQTuvcz/rsGpyZjSomMMO6lwYeQSA0CpWM7+aN7eGoSY/WV6wxJiIxXw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -780,23 +777,23 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 - '@floating-ui/react-dom': 2.0.3(react-dom@18.2.0)(react@18.2.0) - '@mui/types': 7.2.8(@types/react@18.2.37) - '@mui/utils': 5.14.17(@types/react@18.2.37)(react@18.2.0) + '@babel/runtime': 7.23.4 + '@floating-ui/react-dom': 2.0.4(react-dom@18.2.0)(react@18.2.0) + '@mui/types': 7.2.9(@types/react@18.2.38) + '@mui/utils': 5.14.18(@types/react@18.2.38)(react@18.2.0) '@popperjs/core': 2.11.8 - '@types/react': 18.2.37 + '@types/react': 18.2.38 clsx: 2.0.0 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@mui/core-downloads-tracker@5.14.17: - resolution: {integrity: sha512-eE0uxrpJAEL2ZXkeGLKg8HQDafsiXY+6eNpP4lcv3yIjFfGbU6Hj9/P7Adt8jpU+6JIhmxvILGj2r27pX+zdrQ==} + /@mui/core-downloads-tracker@5.14.18: + resolution: {integrity: sha512-yFpF35fEVDV81nVktu0BE9qn2dD/chs7PsQhlyaV3EnTeZi9RZBuvoEfRym1/jmhJ2tcfeWXiRuHG942mQXJJQ==} dev: false - /@mui/joy@5.0.0-beta.14(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0): + /@mui/joy@5.0.0-beta.14(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.38)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-5N4tHgla/YGLRArcDb2GIgz8keXGXOeIdFVyP3hW1IZac0xJpiOuQNelxG9CVcZfEEAZ2V3r22ai7O2yq/8q+A==} engines: {node: '>=12.0.0'} peerDependencies: @@ -813,23 +810,23 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 - '@emotion/react': 11.11.1(@types/react@18.2.37)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.37)(react@18.2.0) - '@mui/base': 5.0.0-beta.23(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0) - '@mui/core-downloads-tracker': 5.14.17 - '@mui/system': 5.14.17(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.37)(react@18.2.0) - '@mui/types': 7.2.8(@types/react@18.2.37) - '@mui/utils': 5.14.17(@types/react@18.2.37)(react@18.2.0) - '@types/react': 18.2.37 + '@babel/runtime': 7.23.4 + '@emotion/react': 11.11.1(@types/react@18.2.38)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.38)(react@18.2.0) + '@mui/base': 5.0.0-beta.23(@types/react@18.2.38)(react-dom@18.2.0)(react@18.2.0) + '@mui/core-downloads-tracker': 5.14.18 + '@mui/system': 5.14.18(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.38)(react@18.2.0) + '@mui/types': 7.2.9(@types/react@18.2.38) + '@mui/utils': 5.14.18(@types/react@18.2.38)(react@18.2.0) + '@types/react': 18.2.38 clsx: 2.0.0 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@mui/private-theming@5.14.17(@types/react@18.2.37)(react@18.2.0): - resolution: {integrity: sha512-u4zxsCm9xmQrlhVPug+Ccrtsjv7o2+rehvrgHoh0siSguvVgVQq5O3Hh10+tp/KWQo2JR4/nCEwquSXgITS1+g==} + /@mui/private-theming@5.14.18(@types/react@18.2.38)(react@18.2.0): + resolution: {integrity: sha512-WSgjqRlzfHU+2Rou3HlR2Gqfr4rZRsvFgataYO3qQ0/m6gShJN+lhVEvwEiJ9QYyVzMDvNpXZAcqp8Y2Vl+PAw==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -838,15 +835,15 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 - '@mui/utils': 5.14.17(@types/react@18.2.37)(react@18.2.0) - '@types/react': 18.2.37 + '@babel/runtime': 7.23.4 + '@mui/utils': 5.14.18(@types/react@18.2.38)(react@18.2.0) + '@types/react': 18.2.38 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/styled-engine@5.14.17(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0): - resolution: {integrity: sha512-AqpVjBEA7wnBvKPW168bNlqB6EN7HxTjLOY7oi275AzD/b1C7V0wqELy6NWoJb2yya5sRf7ENf4iNi3+T5cOgw==} + /@mui/styled-engine@5.14.18(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0): + resolution: {integrity: sha512-pW8bpmF9uCB5FV2IPk6mfbQCjPI5vGI09NOLhtGXPeph/4xIfC3JdIX0TILU0WcTs3aFQqo6s2+1SFgIB9rCXA==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.4.1 @@ -858,17 +855,17 @@ packages: '@emotion/styled': optional: true dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.4 '@emotion/cache': 11.11.0 - '@emotion/react': 11.11.1(@types/react@18.2.37)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.37)(react@18.2.0) + '@emotion/react': 11.11.1(@types/react@18.2.38)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.38)(react@18.2.0) csstype: 3.1.2 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/system@5.14.17(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.37)(react@18.2.0): - resolution: {integrity: sha512-Ccz3XlbCqka6DnbHfpL3o3TfOeWQPR+ewvNAgm8gnS9M0yVMmzzmY6z0w/C1eebb+7ZP7IoLUj9vojg/GBaTPg==} + /@mui/system@5.14.18(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.2.38)(react@18.2.0): + resolution: {integrity: sha512-hSQQdb3KF72X4EN2hMEiv8EYJZSflfdd1TRaGPoR7CIAG347OxCslpBUwWngYobaxgKvq6xTrlIl+diaactVww==} engines: {node: '>=12.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -883,33 +880,33 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 - '@emotion/react': 11.11.1(@types/react@18.2.37)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.37)(react@18.2.0) - '@mui/private-theming': 5.14.17(@types/react@18.2.37)(react@18.2.0) - '@mui/styled-engine': 5.14.17(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0) - '@mui/types': 7.2.8(@types/react@18.2.37) - '@mui/utils': 5.14.17(@types/react@18.2.37)(react@18.2.0) - '@types/react': 18.2.37 + '@babel/runtime': 7.23.4 + '@emotion/react': 11.11.1(@types/react@18.2.38)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.38)(react@18.2.0) + '@mui/private-theming': 5.14.18(@types/react@18.2.38)(react@18.2.0) + '@mui/styled-engine': 5.14.18(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0) + '@mui/types': 7.2.9(@types/react@18.2.38) + '@mui/utils': 5.14.18(@types/react@18.2.38)(react@18.2.0) + '@types/react': 18.2.38 clsx: 2.0.0 csstype: 3.1.2 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/types@7.2.8(@types/react@18.2.37): - resolution: {integrity: sha512-9u0ji+xspl96WPqvrYJF/iO+1tQ1L5GTaDOeG3vCR893yy7VcWwRNiVMmPdPNpMDqx0WV1wtEW9OMwK9acWJzQ==} + /@mui/types@7.2.9(@types/react@18.2.38): + resolution: {integrity: sha512-k1lN/PolaRZfNsRdAqXtcR71sTnv3z/VCCGPxU8HfdftDkzi335MdJ6scZxvofMAd/K/9EbzCZTFBmlNpQVdCg==} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 peerDependenciesMeta: '@types/react': optional: true dependencies: - '@types/react': 18.2.37 + '@types/react': 18.2.38 dev: false - /@mui/utils@5.14.17(@types/react@18.2.37)(react@18.2.0): - resolution: {integrity: sha512-yxnWgSS4J6DMFPw2Dof85yBkG02VTbEiqsikymMsnZnXDurtVGTIhlNuV24GTmFTuJMzEyTTU9UF+O7zaL8LEQ==} + /@mui/utils@5.14.18(@types/react@18.2.38)(react@18.2.0): + resolution: {integrity: sha512-HZDRsJtEZ7WMSnrHV9uwScGze4wM/Y+u6pDVo+grUjt5yXzn+wI8QX/JwTHh9YSw/WpnUL80mJJjgCnWj2VrzQ==} engines: {node: '>=12.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -918,9 +915,9 @@ packages: '@types/react': optional: true dependencies: - '@babel/runtime': 7.23.2 - '@types/prop-types': 15.7.10 - '@types/react': 18.2.37 + '@babel/runtime': 7.23.4 + '@types/prop-types': 15.7.11 + '@types/react': 18.2.38 prop-types: 15.8.1 react: 18.2.0 react-is: 18.2.0 @@ -991,7 +988,7 @@ packages: resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} dev: true - /@reduxjs/toolkit@1.9.7(react-redux@8.1.3)(react@18.2.0): + /@reduxjs/toolkit@1.9.7(react@18.2.0): resolution: {integrity: sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==} peerDependencies: react: ^16.9.0 || ^17.0.0 || ^18 @@ -1004,19 +1001,18 @@ packages: dependencies: immer: 9.0.21 react: 18.2.0 - react-redux: 8.1.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) redux: 4.2.1 redux-thunk: 2.4.2(redux@4.2.1) reselect: 4.1.8 dev: false - /@remix-run/router@1.11.0: - resolution: {integrity: sha512-BHdhcWgeiudl91HvVa2wxqZjSHbheSgIiDvxrF1VjFzBzpTtuDPkOdOi3Iqvc08kXtFkLjhbS+ML9aM8mJS+wQ==} + /@remix-run/router@1.12.0: + resolution: {integrity: sha512-2hXv036Bux90e1GXTWSMfNzfDDK8LA8JYEWfyHxzvwdp6GyoWEovKc9cotb3KCKmkdwsIBuFGX7ScTWyiHv7Eg==} engines: {node: '>=14.0.0'} dev: false - /@swc/core-darwin-arm64@1.3.96: - resolution: {integrity: sha512-8hzgXYVd85hfPh6mJ9yrG26rhgzCmcLO0h1TIl8U31hwmTbfZLzRitFQ/kqMJNbIBCwmNH1RU2QcJnL3d7f69A==} + /@swc/core-darwin-arm64@1.3.99: + resolution: {integrity: sha512-Qj7Jct68q3ZKeuJrjPx7k8SxzWN6PqLh+VFxzA+KwLDpQDPzOlKRZwkIMzuFjLhITO4RHgSnXoDk/Syz0ZeN+Q==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] @@ -1024,8 +1020,8 @@ packages: dev: true optional: true - /@swc/core-darwin-x64@1.3.96: - resolution: {integrity: sha512-mFp9GFfuPg+43vlAdQZl0WZpZSE8sEzqL7sr/7Reul5McUHP0BaLsEzwjvD035ESfkY8GBZdLpMinblIbFNljQ==} + /@swc/core-darwin-x64@1.3.99: + resolution: {integrity: sha512-wR7m9QVJjgiBu1PSOHy7s66uJPa45Kf9bZExXUL+JAa9OQxt5y+XVzr+n+F045VXQOwdGWplgPnWjgbUUHEVyw==} engines: {node: '>=10'} cpu: [x64] os: [darwin] @@ -1033,17 +1029,8 @@ packages: dev: true optional: true - /@swc/core-linux-arm-gnueabihf@1.3.96: - resolution: {integrity: sha512-8UEKkYJP4c8YzYIY/LlbSo8z5Obj4hqcv/fUTHiEePiGsOddgGf7AWjh56u7IoN/0uEmEro59nc1ChFXqXSGyg==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@swc/core-linux-arm64-gnu@1.3.96: - resolution: {integrity: sha512-c/IiJ0s1y3Ymm2BTpyC/xr6gOvoqAVETrivVXHq68xgNms95luSpbYQ28rqaZC8bQC8M5zdXpSc0T8DJu8RJGw==} + /@swc/core-linux-arm64-gnu@1.3.99: + resolution: {integrity: sha512-gcGv1l5t0DScEONmw5OhdVmEI/o49HCe9Ik38zzH0NtDkc+PDYaCcXU5rvfZP2qJFaAAr8cua8iJcOunOSLmnA==} engines: {node: '>=10'} cpu: [arm64] os: [linux] @@ -1051,8 +1038,8 @@ packages: dev: true optional: true - /@swc/core-linux-arm64-musl@1.3.96: - resolution: {integrity: sha512-i5/UTUwmJLri7zhtF6SAo/4QDQJDH2fhYJaBIUhrICmIkRO/ltURmpejqxsM/ye9Jqv5zG7VszMC0v/GYn/7BQ==} + /@swc/core-linux-arm64-musl@1.3.99: + resolution: {integrity: sha512-XL1/eUsTO8BiKsWq9i3iWh7H99iPO61+9HYiWVKhSavknfj4Plbn+XyajDpxsauln5o8t+BRGitymtnAWJM4UQ==} engines: {node: '>=10'} cpu: [arm64] os: [linux] @@ -1060,8 +1047,8 @@ packages: dev: true optional: true - /@swc/core-linux-x64-gnu@1.3.96: - resolution: {integrity: sha512-USdaZu8lTIkm4Yf9cogct/j5eqtdZqTgcTib4I+NloUW0E/hySou3eSyp3V2UAA1qyuC72ld1otXuyKBna0YKQ==} + /@swc/core-linux-x64-gnu@1.3.99: + resolution: {integrity: sha512-fGrXYE6DbTfGNIGQmBefYxSk3rp/1lgbD0nVg4rl4mfFRQPi7CgGhrrqSuqZ/ezXInUIgoCyvYGWFSwjLXt/Qg==} engines: {node: '>=10'} cpu: [x64] os: [linux] @@ -1069,8 +1056,8 @@ packages: dev: true optional: true - /@swc/core-linux-x64-musl@1.3.96: - resolution: {integrity: sha512-QYErutd+G2SNaCinUVobfL7jWWjGTI0QEoQ6hqTp7PxCJS/dmKmj3C5ZkvxRYcq7XcZt7ovrYCTwPTHzt6lZBg==} + /@swc/core-linux-x64-musl@1.3.99: + resolution: {integrity: sha512-kvgZp/mqf3IJ806gUOL6gN6VU15+DfzM1Zv4Udn8GqgXiUAvbQehrtruid4Snn5pZTLj4PEpSCBbxgxK1jbssA==} engines: {node: '>=10'} cpu: [x64] os: [linux] @@ -1078,8 +1065,8 @@ packages: dev: true optional: true - /@swc/core-win32-arm64-msvc@1.3.96: - resolution: {integrity: sha512-hjGvvAduA3Un2cZ9iNP4xvTXOO4jL3G9iakhFsgVhpkU73SGmK7+LN8ZVBEu4oq2SUcHO6caWvnZ881cxGuSpg==} + /@swc/core-win32-arm64-msvc@1.3.99: + resolution: {integrity: sha512-yt8RtZ4W/QgFF+JUemOUQAkVW58cCST7mbfKFZ1v16w3pl3NcWd9OrtppFIXpbjU1rrUX2zp2R7HZZzZ2Zk/aQ==} engines: {node: '>=10'} cpu: [arm64] os: [win32] @@ -1087,8 +1074,8 @@ packages: dev: true optional: true - /@swc/core-win32-ia32-msvc@1.3.96: - resolution: {integrity: sha512-Far2hVFiwr+7VPCM2GxSmbh3ikTpM3pDombE+d69hkedvYHYZxtTF+2LTKl/sXtpbUnsoq7yV/32c9R/xaaWfw==} + /@swc/core-win32-ia32-msvc@1.3.99: + resolution: {integrity: sha512-62p5fWnOJR/rlbmbUIpQEVRconICy5KDScWVuJg1v3GPLBrmacjphyHiJC1mp6dYvvoEWCk/77c/jcQwlXrDXw==} engines: {node: '>=10'} cpu: [ia32] os: [win32] @@ -1096,8 +1083,8 @@ packages: dev: true optional: true - /@swc/core-win32-x64-msvc@1.3.96: - resolution: {integrity: sha512-4VbSAniIu0ikLf5mBX81FsljnfqjoVGleEkCQv4+zRlyZtO3FHoDPkeLVoy6WRlj7tyrRcfUJ4mDdPkbfTO14g==} + /@swc/core-win32-x64-msvc@1.3.99: + resolution: {integrity: sha512-PdppWhkoS45VGdMBxvClVgF1hVjqamtvYd82Gab1i4IV45OSym2KinoDCKE1b6j3LwBLOn2J9fvChGSgGfDCHQ==} engines: {node: '>=10'} cpu: [x64] os: [win32] @@ -1105,8 +1092,8 @@ packages: dev: true optional: true - /@swc/core@1.3.96: - resolution: {integrity: sha512-zwE3TLgoZwJfQygdv2SdCK9mRLYluwDOM53I+dT6Z5ZvrgVENmY3txvWDvduzkV+/8IuvrRbVezMpxcojadRdQ==} + /@swc/core@1.3.99: + resolution: {integrity: sha512-8O996RfuPC4ieb4zbYMfbyCU9k4gSOpyCNnr7qBQ+o7IEmh8JCV6B8wwu+fT/Om/6Lp34KJe1IpJ/24axKS6TQ==} engines: {node: '>=10'} requiresBuild: true peerDependencies: @@ -1118,16 +1105,15 @@ packages: '@swc/counter': 0.1.2 '@swc/types': 0.1.5 optionalDependencies: - '@swc/core-darwin-arm64': 1.3.96 - '@swc/core-darwin-x64': 1.3.96 - '@swc/core-linux-arm-gnueabihf': 1.3.96 - '@swc/core-linux-arm64-gnu': 1.3.96 - '@swc/core-linux-arm64-musl': 1.3.96 - '@swc/core-linux-x64-gnu': 1.3.96 - '@swc/core-linux-x64-musl': 1.3.96 - '@swc/core-win32-arm64-msvc': 1.3.96 - '@swc/core-win32-ia32-msvc': 1.3.96 - '@swc/core-win32-x64-msvc': 1.3.96 + '@swc/core-darwin-arm64': 1.3.99 + '@swc/core-darwin-x64': 1.3.99 + '@swc/core-linux-arm64-gnu': 1.3.99 + '@swc/core-linux-arm64-musl': 1.3.99 + '@swc/core-linux-x64-gnu': 1.3.99 + '@swc/core-linux-x64-musl': 1.3.99 + '@swc/core-win32-arm64-msvc': 1.3.99 + '@swc/core-win32-ia32-msvc': 1.3.99 + '@swc/core-win32-x64-msvc': 1.3.99 dev: true /@swc/counter@0.1.2: @@ -1138,8 +1124,8 @@ packages: resolution: {integrity: sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==} dev: true - /@trivago/prettier-plugin-sort-imports@4.2.1(prettier@2.6.2): - resolution: {integrity: sha512-iuy2MPVURGdxILTchHr15VAioItuYBejKfcTmQFlxIuqA7jeaT6ngr5aUIG6S6U096d6a6lJCgaOwlRrPLlOPg==} + /@trivago/prettier-plugin-sort-imports@4.3.0(prettier@2.6.2): + resolution: {integrity: sha512-r3n0onD3BTOVUNPhR4lhVK4/pABGpbA7bW3eumZnYdKaHkf1qEC+Mag6DPbGNuuh0eG8AaYj+YqmVHSiGslaTQ==} peerDependencies: '@vue/compiler-sfc': 3.x prettier: 2.x - 3.x @@ -1148,7 +1134,7 @@ packages: optional: true dependencies: '@babel/generator': 7.17.7 - '@babel/parser': 7.23.3 + '@babel/parser': 7.23.4 '@babel/traverse': 7.23.2 '@babel/types': 7.17.0 javascript-natural-sort: 0.7.1 @@ -1158,13 +1144,6 @@ packages: - supports-color dev: true - /@types/hoist-non-react-statics@3.3.5: - resolution: {integrity: sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==} - dependencies: - '@types/react': 18.2.37 - hoist-non-react-statics: 3.3.2 - dev: false - /@types/js-cookie@2.2.7: resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==} dev: false @@ -1176,15 +1155,15 @@ packages: /@types/lodash-es@4.17.11: resolution: {integrity: sha512-eCw8FYAWHt2DDl77s+AMLLzPn310LKohruumpucZI4oOFJkIgnlaJcy23OKMJxx4r9PeTF13Gv6w+jqjWQaYUg==} dependencies: - '@types/lodash': 4.14.201 + '@types/lodash': 4.14.202 dev: true - /@types/lodash@4.14.201: - resolution: {integrity: sha512-y9euML0cim1JrykNxADLfaG0FgD1g/yTHwUs/Jg9ZIU7WKj2/4IW9Lbb1WZbvck78W/lfGXFfe+u2EGfIJXdLQ==} + /@types/lodash@4.14.202: + resolution: {integrity: sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==} dev: true - /@types/node@20.9.0: - resolution: {integrity: sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==} + /@types/node@20.9.3: + resolution: {integrity: sha512-nk5wXLAXGBKfrhLB0cyHGbSqopS+nz0BUgZkUQqSHSSgdee0kssp1IAqlQOu333bW+gMNs2QREx7iynm19Abxw==} dependencies: undici-types: 5.26.5 dev: true @@ -1193,34 +1172,31 @@ packages: resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} dev: false - /@types/prop-types@15.7.10: - resolution: {integrity: sha512-mxSnDQxPqsZxmeShFH+uwQ4kO4gcJcGahjjMFeLbKE95IAZiiZyiEepGZjtXJ7hN/yfu0bu9xN2ajcU0JcxX6A==} + /@types/prop-types@15.7.11: + resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} - /@types/react-dom@18.2.15: - resolution: {integrity: sha512-HWMdW+7r7MR5+PZqJF6YFNSCtjz1T0dsvo/f1BV6HkV+6erD/nA7wd9NM00KVG83zf2nJ7uATPO9ttdIPvi3gg==} + /@types/react-dom@18.2.16: + resolution: {integrity: sha512-766c37araZ9vxtYs25gvY2wNdFWsT2ZiUvOd0zMhTaoGj6B911N8CKQWgXXJoPMLF3J82thpRqQA7Rf3rBwyJw==} dependencies: - '@types/react': 18.2.37 - - /@types/react@18.2.37: - resolution: {integrity: sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==} - dependencies: - '@types/prop-types': 15.7.10 - '@types/scheduler': 0.16.6 - csstype: 3.1.2 - - /@types/scheduler@0.16.6: - resolution: {integrity: sha512-Vlktnchmkylvc9SnwwwozTv04L/e1NykF5vgoQ0XTmI8DD+wxfjQuHuvHS3p0r2jz2x2ghPs2h1FVeDirIteWA==} - - /@types/semver@7.5.5: - resolution: {integrity: sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==} + '@types/react': 18.2.38 dev: true - /@types/use-sync-external-store@0.0.3: - resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==} - dev: false + /@types/react@18.2.38: + resolution: {integrity: sha512-cBBXHzuPtQK6wNthuVMV6IjHAFkdl/FOPFIlkd81/Cd1+IqkHu/A+w4g43kaQQoYHik/ruaQBDL72HyCy1vuMw==} + dependencies: + '@types/prop-types': 15.7.11 + '@types/scheduler': 0.16.7 + csstype: 3.1.2 - /@typescript-eslint/eslint-plugin@6.10.0(@typescript-eslint/parser@6.10.0)(eslint@8.53.0)(typescript@5.2.2): - resolution: {integrity: sha512-uoLj4g2OTL8rfUQVx2AFO1hp/zja1wABJq77P6IclQs6I/m9GLrm7jCdgzZkvWdDCQf1uEvoa8s8CupsgWQgVg==} + /@types/scheduler@0.16.7: + resolution: {integrity: sha512-8g25Nl3AuB1KulTlSUsUhUo/oBgBU6XIXQ+XURpeioEbEJvkO7qI4vDfREv3vJYHHzqXjcAHvoJy4pTtSQNZtA==} + + /@types/semver@7.5.6: + resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==} + dev: true + + /@typescript-eslint/eslint-plugin@6.12.0(@typescript-eslint/parser@6.12.0)(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-XOpZ3IyJUIV1b15M7HVOpgQxPPF7lGXgsfcEIu3yDxFPaf/xZKt7s9QO/pbk7vpWQyVulpJbu4E5LwpZiQo4kA==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha @@ -1231,25 +1207,25 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 6.10.0(eslint@8.53.0)(typescript@5.2.2) - '@typescript-eslint/scope-manager': 6.10.0 - '@typescript-eslint/type-utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) - '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.10.0 + '@typescript-eslint/parser': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/scope-manager': 6.12.0 + '@typescript-eslint/type-utils': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.3.2) + '@typescript-eslint/visitor-keys': 6.12.0 debug: 4.3.4 - eslint: 8.53.0 + eslint: 8.54.0 graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.0 natural-compare: 1.4.0 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.2.2) - typescript: 5.2.2 + ts-api-utils: 1.0.3(typescript@5.3.2) + typescript: 5.3.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@6.10.0(eslint@8.53.0)(typescript@5.2.2): - resolution: {integrity: sha512-+sZwIj+s+io9ozSxIWbNB5873OSdfeBEH/FR0re14WLI6BaKuSOnnwCJ2foUiu8uXf4dRp1UqHP0vrZ1zXGrog==} + /@typescript-eslint/parser@6.12.0(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-s8/jNFPKPNRmXEnNXfuo1gemBdVmpQsK1pcu+QIvuNJuhFzGrpD7WjOcvDc/+uEdfzSYpNu7U/+MmbScjoQ6vg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1258,27 +1234,27 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 6.10.0 - '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) - '@typescript-eslint/visitor-keys': 6.10.0 + '@typescript-eslint/scope-manager': 6.12.0 + '@typescript-eslint/types': 6.12.0 + '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.3.2) + '@typescript-eslint/visitor-keys': 6.12.0 debug: 4.3.4 - eslint: 8.53.0 - typescript: 5.2.2 + eslint: 8.54.0 + typescript: 5.3.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager@6.10.0: - resolution: {integrity: sha512-TN/plV7dzqqC2iPNf1KrxozDgZs53Gfgg5ZHyw8erd6jd5Ta/JIEcdCheXFt9b1NYb93a1wmIIVW/2gLkombDg==} + /@typescript-eslint/scope-manager@6.12.0: + resolution: {integrity: sha512-5gUvjg+XdSj8pcetdL9eXJzQNTl3RD7LgUiYTl8Aabdi8hFkaGSYnaS6BLc0BGNaDH+tVzVwmKtWvu0jLgWVbw==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/visitor-keys': 6.10.0 + '@typescript-eslint/types': 6.12.0 + '@typescript-eslint/visitor-keys': 6.12.0 dev: true - /@typescript-eslint/type-utils@6.10.0(eslint@8.53.0)(typescript@5.2.2): - resolution: {integrity: sha512-wYpPs3hgTFblMYwbYWPT3eZtaDOjbLyIYuqpwuLBBqhLiuvJ+9sEp2gNRJEtR5N/c9G1uTtQQL5AhV0fEPJYcg==} + /@typescript-eslint/type-utils@6.12.0(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-WWmRXxhm1X8Wlquj+MhsAG4dU/Blvf1xDgGaYCzfvStP2NwPQh6KBvCDbiOEvaE0filhranjIlK/2fSTVwtBng==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 @@ -1287,23 +1263,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) - '@typescript-eslint/utils': 6.10.0(eslint@8.53.0)(typescript@5.2.2) + '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.3.2) + '@typescript-eslint/utils': 6.12.0(eslint@8.54.0)(typescript@5.3.2) debug: 4.3.4 - eslint: 8.53.0 - ts-api-utils: 1.0.3(typescript@5.2.2) - typescript: 5.2.2 + eslint: 8.54.0 + ts-api-utils: 1.0.3(typescript@5.3.2) + typescript: 5.3.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types@6.10.0: - resolution: {integrity: sha512-36Fq1PWh9dusgo3vH7qmQAj5/AZqARky1Wi6WpINxB6SkQdY5vQoT2/7rW7uBIsPDcvvGCLi4r10p0OJ7ITAeg==} + /@typescript-eslint/types@6.12.0: + resolution: {integrity: sha512-MA16p/+WxM5JG/F3RTpRIcuOghWO30//VEOvzubM8zuOOBYXsP+IfjoCXXiIfy2Ta8FRh9+IO9QLlaFQUU+10Q==} engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@6.10.0(typescript@5.2.2): - resolution: {integrity: sha512-ek0Eyuy6P15LJVeghbWhSrBCj/vJpPXXR+EpaRZqou7achUWL8IdYnMSC5WHAeTWswYQuP2hAZgij/bC9fanBg==} + /@typescript-eslint/typescript-estree@6.12.0(typescript@5.3.2): + resolution: {integrity: sha512-vw9E2P9+3UUWzhgjyyVczLWxZ3GuQNT7QpnIY3o5OMeLO/c8oHljGc8ZpryBMIyympiAAaKgw9e5Hl9dCWFOYw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: typescript: '*' @@ -1311,42 +1287,42 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/visitor-keys': 6.10.0 + '@typescript-eslint/types': 6.12.0 + '@typescript-eslint/visitor-keys': 6.12.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 semver: 7.5.4 - ts-api-utils: 1.0.3(typescript@5.2.2) - typescript: 5.2.2 + ts-api-utils: 1.0.3(typescript@5.3.2) + typescript: 5.3.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@6.10.0(eslint@8.53.0)(typescript@5.2.2): - resolution: {integrity: sha512-v+pJ1/RcVyRc0o4wAGux9x42RHmAjIGzPRo538Z8M1tVx6HOnoQBCX/NoadHQlZeC+QO2yr4nNSFWOoraZCAyg==} + /@typescript-eslint/utils@6.12.0(eslint@8.54.0)(typescript@5.3.2): + resolution: {integrity: sha512-LywPm8h3tGEbgfyjYnu3dauZ0U7R60m+miXgKcZS8c7QALO9uWJdvNoP+duKTk2XMWc7/Q3d/QiCuLN9X6SWyQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) '@types/json-schema': 7.0.15 - '@types/semver': 7.5.5 - '@typescript-eslint/scope-manager': 6.10.0 - '@typescript-eslint/types': 6.10.0 - '@typescript-eslint/typescript-estree': 6.10.0(typescript@5.2.2) - eslint: 8.53.0 + '@types/semver': 7.5.6 + '@typescript-eslint/scope-manager': 6.12.0 + '@typescript-eslint/types': 6.12.0 + '@typescript-eslint/typescript-estree': 6.12.0(typescript@5.3.2) + eslint: 8.54.0 semver: 7.5.4 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys@6.10.0: - resolution: {integrity: sha512-xMGluxQIEtOM7bqFCo+rCMh5fqI+ZxV5RUUOa29iVPz1OgCZrtc7rFnz5cLUazlkPKYqX+75iuDq7m0HQ48nCg==} + /@typescript-eslint/visitor-keys@6.12.0: + resolution: {integrity: sha512-rg3BizTZHF1k3ipn8gfrzDXXSFKyOEB5zxYXInQ6z0hUvmQlhaZQzK+YmHmNViMA9HzW5Q9+bPPt90bU6GQwyw==} engines: {node: ^16.0.0 || >=18.0.0} dependencies: - '@typescript-eslint/types': 6.10.0 + '@typescript-eslint/types': 6.12.0 eslint-visitor-keys: 3.4.3 dev: true @@ -1354,12 +1330,12 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true - /@vitejs/plugin-react-swc@3.4.1(vite@4.5.0): - resolution: {integrity: sha512-7YQOQcVV5x1luD8nkbCDdyYygFvn1hjqJk68UvNAzY2QG4o4N5EwAhLLFNOcd1HrdMwDl0VElP8VutoWf9IvJg==} + /@vitejs/plugin-react-swc@3.5.0(vite@4.5.0): + resolution: {integrity: sha512-1PrOvAaDpqlCV+Up8RkAh9qaiUjoDUcjtttyhXDKw53XA6Ve16SOp6cCOpRs8Dj8DqUQs6eTW5YkLcLJjrXAig==} peerDependencies: - vite: ^4 + vite: ^4 || ^5 dependencies: - '@swc/core': 1.3.96 + '@swc/core': 1.3.99 vite: 4.5.0 transitivePeerDependencies: - '@swc/helpers' @@ -1518,7 +1494,7 @@ packages: postcss: ^8.1.0 dependencies: browserslist: 4.22.1 - caniuse-lite: 1.0.30001561 + caniuse-lite: 1.0.30001563 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 @@ -1531,8 +1507,8 @@ packages: engines: {node: '>= 0.4'} dev: true - /axios@1.6.0: - resolution: {integrity: sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==} + /axios@1.6.2: + resolution: {integrity: sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==} dependencies: follow-redirects: 1.15.3 form-data: 4.0.0 @@ -1545,7 +1521,7 @@ packages: resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} engines: {node: '>=10', npm: '>=6'} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.4 cosmiconfig: 7.1.0 resolve: 1.22.8 dev: false @@ -1575,8 +1551,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001561 - electron-to-chromium: 1.4.579 + caniuse-lite: 1.0.30001563 + electron-to-chromium: 1.4.589 node-releases: 2.0.13 update-browserslist-db: 1.0.13(browserslist@4.22.1) dev: true @@ -1598,8 +1574,8 @@ packages: engines: {node: '>= 6'} dev: false - /caniuse-lite@1.0.30001561: - resolution: {integrity: sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==} + /caniuse-lite@1.0.30001563: + resolution: {integrity: sha512-na2WUmOxnwIZtwnFI2CZ/3er0wdNzU7hN+cPYz/z2ajHThnkWjNBOpEPP4n+4r2WPM847JaMotaJE3bnfzjyKw==} dev: true /chalk@2.4.2: @@ -1801,8 +1777,8 @@ packages: esutils: 2.0.3 dev: true - /electron-to-chromium@1.4.579: - resolution: {integrity: sha512-bJKvA+awBIzYR0xRced7PrQuRIwGQPpo6ZLP62GAShahU9fWpsNN2IP6BSP1BLDDSbxvBVRGAMWlvVVq3npmLA==} + /electron-to-chromium@1.4.589: + resolution: {integrity: sha512-zF6y5v/YfoFIgwf2dDfAqVlPPsyQeWNpEWXbAlDUS8Ax4Z2VoiiZpAPC0Jm9hXEkJm2vIZpwB6rc4KnLTQffbQ==} dev: true /error-ex@1.3.2: @@ -1948,16 +1924,16 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - /eslint-config-prettier@8.10.0(eslint@8.53.0): + /eslint-config-prettier@8.10.0(eslint@8.54.0): resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} hasBin: true peerDependencies: eslint: '>=7.0.0' dependencies: - eslint: 8.53.0 + eslint: 8.54.0 dev: true - /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0)(eslint@8.53.0)(prettier@2.6.2): + /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.10.0)(eslint@8.54.0)(prettier@2.6.2): resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1968,13 +1944,13 @@ packages: eslint-config-prettier: optional: true dependencies: - eslint: 8.53.0 - eslint-config-prettier: 8.10.0(eslint@8.53.0) + eslint: 8.54.0 + eslint-config-prettier: 8.10.0(eslint@8.54.0) prettier: 2.6.2 prettier-linter-helpers: 1.0.0 dev: true - /eslint-plugin-react@7.33.2(eslint@8.53.0): + /eslint-plugin-react@7.33.2(eslint@8.54.0): resolution: {integrity: sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==} engines: {node: '>=4'} peerDependencies: @@ -1985,7 +1961,7 @@ packages: array.prototype.tosorted: 1.1.2 doctrine: 2.1.0 es-iterator-helpers: 1.0.15 - eslint: 8.53.0 + eslint: 8.54.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.5 minimatch: 3.1.2 @@ -2012,15 +1988,15 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.53.0: - resolution: {integrity: sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==} + /eslint@8.54.0: + resolution: {integrity: sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.53.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.54.0) '@eslint-community/regexpp': 4.10.0 '@eslint/eslintrc': 2.1.3 - '@eslint/js': 8.53.0 + '@eslint/js': 8.54.0 '@humanwhocodes/config-array': 0.11.13 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -2042,7 +2018,7 @@ packages: glob-parent: 6.0.2 globals: 13.23.0 graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.0 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -2138,7 +2114,7 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: - flat-cache: 3.1.1 + flat-cache: 3.2.0 dev: true /fill-range@7.0.1: @@ -2159,9 +2135,9 @@ packages: path-exists: 4.0.0 dev: true - /flat-cache@3.1.1: - resolution: {integrity: sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q==} - engines: {node: '>=12.0.0'} + /flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} dependencies: flatted: 3.2.9 keyv: 4.5.4 @@ -2305,7 +2281,7 @@ packages: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.3.2 - ignore: 5.2.4 + ignore: 5.3.0 merge2: 1.4.1 slash: 3.0.0 dev: true @@ -2386,14 +2362,14 @@ packages: resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==} dev: false - /i18next@23.6.0: - resolution: {integrity: sha512-z0Cxr0MGkt+kli306WS4nNNM++9cgt2b2VCMprY92j+AIab/oclgPxdwtTZVLP1zn5t5uo8M6uLsZmYrcjr3HA==} + /i18next@23.7.6: + resolution: {integrity: sha512-O66BhXBw0fH4bEJMA0/klQKPEbcwAp5wjXEL803pdAynNbg2f4qhLIYlNHJyE7icrL6XmSZKPYaaXwy11kJ6YQ==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.4 dev: false - /ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + /ignore@5.3.0: + resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} engines: {node: '>= 4'} dev: true @@ -2422,8 +2398,8 @@ packages: /inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - /inline-style-prefixer@6.0.4: - resolution: {integrity: sha512-FwXmZC2zbeeS7NzGjJ6pAiqRhXR0ugUShSNb6GApMl6da0/XGc4MOJsoWAywia52EEWbXNSy0pzkwz/+Y+swSg==} + /inline-style-prefixer@7.0.0: + resolution: {integrity: sha512-I7GEdScunP1dQ6IM2mQWh6v0mOYdYmH3Bp31UecKdrcUgcURTcctSe1IECdUznSHKSmsHtjrT3CwCPI1pyxfUQ==} dependencies: css-in-js-utils: 3.1.0 fast-loops: 1.1.3 @@ -2703,6 +2679,11 @@ packages: engines: {node: '>=10'} dev: false + /lilconfig@3.0.0: + resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} + engines: {node: '>=14'} + dev: false + /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: false @@ -2795,20 +2776,20 @@ packages: thenify-all: 1.6.0 dev: false - /nano-css@5.3.5(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-vSB9X12bbNu4ALBu7nigJgRViZ6ja3OU7CeuiV1zMIbXOdmkLahgtPmh3GBOlDxbKY0CitqlPdOReGlBLSp+yg==} + /nano-css@5.6.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-jNikscxQv93wwhmXN4w6XC1HVllqo3UvK2u7PRqjOfMJaD5gGkGvECgLxtILndQrWMUr4Mn8I4VurUyxMOipFw==} peerDependencies: react: '*' react-dom: '*' dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 css-tree: 1.1.3 csstype: 3.1.2 fastest-stable-stringify: 2.0.2 - inline-style-prefixer: 6.0.4 + inline-style-prefixer: 7.0.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) rtl-css-js: 1.16.1 - sourcemap-codec: 1.4.8 stacktrace-js: 2.0.2 stylis: 4.3.0 dev: false @@ -2956,7 +2937,7 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: - '@babel/code-frame': 7.22.13 + '@babel/code-frame': 7.23.4 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -3022,8 +3003,8 @@ packages: postcss: 8.4.31 dev: false - /postcss-load-config@4.0.1(postcss@8.4.31): - resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} + /postcss-load-config@4.0.2(postcss@8.4.31): + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} engines: {node: '>= 14'} peerDependencies: postcss: '>=8.0.9' @@ -3034,7 +3015,7 @@ packages: ts-node: optional: true dependencies: - lilconfig: 2.1.0 + lilconfig: 3.0.0 postcss: 8.4.31 yaml: 2.3.4 dev: false @@ -3108,7 +3089,7 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 20.9.0 + '@types/node': 20.9.3 long: 5.2.3 dev: true @@ -3156,8 +3137,8 @@ packages: - csstype dev: false - /react-i18next@13.3.1(i18next@23.6.0)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-JAtYREK879JXaN9GdzfBI4yJeo/XyLeXWUsRABvYXiFUakhZJ40l+kaTo+i+A/3cKIED41kS/HAbZ5BzFtq/Og==} + /react-i18next@13.5.0(i18next@23.7.6)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-CFJ5NDGJ2MUyBohEHxljOq/39NQ972rh1ajnadG9BjTk+UXbHLq4z5DKEbEQBDoIhUmmbuS/fIMJKo6VOax1HA==} peerDependencies: i18next: '>= 23.2.3' react: '>= 16.8.0' @@ -3169,9 +3150,9 @@ packages: react-native: optional: true dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.4 html-parse-stringify: 3.0.1 - i18next: 23.6.0 + i18next: 23.7.6 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false @@ -3183,60 +3164,26 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: false - /react-redux@8.1.3(@types/react-dom@18.2.15)(@types/react@18.2.37)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1): - resolution: {integrity: sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==} - peerDependencies: - '@types/react': ^16.8 || ^17.0 || ^18.0 - '@types/react-dom': ^16.8 || ^17.0 || ^18.0 - react: ^16.8 || ^17.0 || ^18.0 - react-dom: ^16.8 || ^17.0 || ^18.0 - react-native: '>=0.59' - redux: ^4 || ^5.0.0-beta.0 - peerDependenciesMeta: - '@types/react': - optional: true - '@types/react-dom': - optional: true - react-dom: - optional: true - react-native: - optional: true - redux: - optional: true - dependencies: - '@babel/runtime': 7.23.2 - '@types/hoist-non-react-statics': 3.3.5 - '@types/react': 18.2.37 - '@types/react-dom': 18.2.15 - '@types/use-sync-external-store': 0.0.3 - hoist-non-react-statics: 3.3.2 - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - react-is: 18.2.0 - redux: 4.2.1 - use-sync-external-store: 1.2.0(react@18.2.0) - dev: false - - /react-router-dom@6.18.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-Ubrue4+Ercc/BoDkFQfc6og5zRQ4A8YxSO3Knsne+eRbZ+IepAsK249XBH/XaFuOYOYr3L3r13CXTLvYt5JDjw==} + /react-router-dom@6.19.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-N6dWlcgL2w0U5HZUUqU2wlmOrSb3ighJmtQ438SWbhB1yuLTXQ8yyTBMK3BSvVjp7gBtKurT554nCtMOgxCZmQ==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' dependencies: - '@remix-run/router': 1.11.0 + '@remix-run/router': 1.12.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-router: 6.18.0(react@18.2.0) + react-router: 6.19.0(react@18.2.0) dev: false - /react-router@6.18.0(react@18.2.0): - resolution: {integrity: sha512-vk2y7Dsy8wI02eRRaRmOs9g2o+aE72YCx5q9VasT1N9v+lrdB79tIqrjMfByHiY5+6aYkH2rUa5X839nwWGPDg==} + /react-router@6.19.0(react@18.2.0): + resolution: {integrity: sha512-0W63PKCZ7+OuQd7Tm+RbkI8kCLmn4GPjDbX61tWljPxWgqTKlEpeQUwPkT1DRjYhF8KSihK0hQpmhU4uxVMcdw==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' dependencies: - '@remix-run/router': 1.11.0 + '@remix-run/router': 1.12.0 react: 18.2.0 dev: false @@ -3262,7 +3209,7 @@ packages: fast-deep-equal: 3.1.3 fast-shallow-equal: 1.0.0 js-cookie: 2.2.1 - nano-css: 5.3.5(react-dom@18.2.0)(react@18.2.0) + nano-css: 5.6.0(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-universal-interface: 0.6.2(react@18.2.0)(tslib@2.6.2) @@ -3305,7 +3252,7 @@ packages: /redux@4.2.1: resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.4 dev: false /reflect.getprototypeof@1.0.4: @@ -3385,7 +3332,7 @@ packages: /rtl-css-js@1.16.1: resolution: {integrity: sha512-lRQgou1mu19e+Ya0LsTvKrVJ5TYUbqCVPAiImX3UfLTenarvPUl1QFdvu5Z3PYmHT9RCcwIfbjRQBntExyj3Zg==} dependencies: - '@babel/runtime': 7.23.2 + '@babel/runtime': 7.23.4 dev: false /run-parallel@1.2.0: @@ -3502,11 +3449,6 @@ packages: engines: {node: '>=0.10.0'} dev: false - /sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - dev: false - /stack-generator@2.0.10: resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==} dependencies: @@ -3644,7 +3586,7 @@ packages: postcss: 8.4.31 postcss-import: 15.1.0(postcss@8.4.31) postcss-js: 4.0.1(postcss@8.4.31) - postcss-load-config: 4.0.1(postcss@8.4.31) + postcss-load-config: 4.0.2(postcss@8.4.31) postcss-nested: 6.0.1(postcss@8.4.31) postcss-selector-parser: 6.0.13 resolve: 1.22.8 @@ -3689,13 +3631,13 @@ packages: resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} dev: false - /ts-api-utils@1.0.3(typescript@5.2.2): + /ts-api-utils@1.0.3(typescript@5.3.2): resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} engines: {node: '>=16.13.0'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.2.2 + typescript: 5.3.2 dev: true /ts-easing@0.2.0: @@ -3764,8 +3706,8 @@ packages: is-typed-array: 1.1.12 dev: true - /typescript@5.2.2: - resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + /typescript@5.3.2: + resolution: {integrity: sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==} engines: {node: '>=14.17'} hasBin: true dev: true @@ -3943,7 +3885,7 @@ packages: engines: {node: '>=10'} dev: true - /zustand@4.4.6(@types/react@18.2.37)(react@18.2.0): + /zustand@4.4.6(@types/react@18.2.38)(react@18.2.0): resolution: {integrity: sha512-Rb16eW55gqL4W2XZpJh0fnrATxYEG3Apl2gfHTyDSE965x/zxslTikpNch0JgNjJA9zK6gEFW8Fl6d1rTZaqgg==} engines: {node: '>=12.7.0'} peerDependencies: @@ -3958,7 +3900,7 @@ packages: react: optional: true dependencies: - '@types/react': 18.2.37 + '@types/react': 18.2.38 react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) dev: false diff --git a/frontend/web/src/components/AnalyticsView.tsx b/frontend/web/src/components/AnalyticsView.tsx index b4d1156..c03f062 100644 --- a/frontend/web/src/components/AnalyticsView.tsx +++ b/frontend/web/src/components/AnalyticsView.tsx @@ -5,7 +5,7 @@ import * as api from "../helpers/api"; import Icon from "./Icon"; interface Props { - shortcutId: ShortcutId; + shortcutId: number; className?: string; } diff --git a/frontend/web/src/components/CollectionView.tsx b/frontend/web/src/components/CollectionView.tsx index 004f681..2934dc0 100644 --- a/frontend/web/src/components/CollectionView.tsx +++ b/frontend/web/src/components/CollectionView.tsx @@ -7,10 +7,11 @@ import { Link } from "react-router-dom"; import { absolutifyLink } from "@/helpers/utils"; import useNavigateTo from "@/hooks/useNavigateTo"; import useResponsiveWidth from "@/hooks/useResponsiveWidth"; -import { useAppSelector } from "@/stores"; import useCollectionStore from "@/stores/v1/collection"; +import useShortcutStore from "@/stores/v1/shortcut"; import useUserStore from "@/stores/v1/user"; import { Collection } from "@/types/proto/api/v2/collection_service"; +import { Shortcut } from "@/types/proto/api/v2/shortcut_service"; import { showCommonDialog } from "./Alert"; import CreateCollectionDialog from "./CreateCollectionDrawer"; import Icon from "./Icon"; @@ -28,7 +29,7 @@ const CollectionView = (props: Props) => { const navigateTo = useNavigateTo(); const currentUser = useUserStore().getCurrentUser(); const collectionStore = useCollectionStore(); - const { shortcutList } = useAppSelector((state) => state.shortcut); + const shortcutList = useShortcutStore().getShortcutList(); const [showEditDialog, setShowEditDialog] = useState(false); const shortcuts = collection.shortcutIds .map((shortcutId) => shortcutList.find((shortcut) => shortcut?.id === shortcutId)) diff --git a/frontend/web/src/components/CreateCollectionDrawer.tsx b/frontend/web/src/components/CreateCollectionDrawer.tsx index 9317b5b..b389dd0 100644 --- a/frontend/web/src/components/CreateCollectionDrawer.tsx +++ b/frontend/web/src/components/CreateCollectionDrawer.tsx @@ -3,10 +3,11 @@ import { isUndefined } from "lodash-es"; import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import { useTranslation } from "react-i18next"; -import { useAppSelector } from "@/stores"; import useCollectionStore from "@/stores/v1/collection"; +import useShortcutStore from "@/stores/v1/shortcut"; import { Collection } from "@/types/proto/api/v2/collection_service"; import { Visibility } from "@/types/proto/api/v2/common"; +import { Shortcut } from "@/types/proto/api/v2/shortcut_service"; import { convertVisibilityFromPb } from "@/utils/visibility"; import useLoading from "../hooks/useLoading"; import Icon from "./Icon"; @@ -27,7 +28,7 @@ const CreateCollectionDrawer: React.FC = (props: Props) => { const { onClose, onConfirm, collectionId } = props; const { t } = useTranslation(); const collectionStore = useCollectionStore(); - const { shortcutList } = useAppSelector((state) => state.shortcut); + const shortcutList = useShortcutStore().getShortcutList(); const [state, setState] = useState({ collectionCreate: Collection.fromPartial({ visibility: Visibility.PRIVATE, @@ -40,9 +41,9 @@ const CreateCollectionDrawer: React.FC = (props: Props) => { const unselectedShortcuts = shortcutList .filter((shortcut) => { if (state.collectionCreate.visibility === Visibility.PUBLIC) { - return shortcut.visibility === "PUBLIC"; + return shortcut.visibility === Visibility.PUBLIC; } else if (state.collectionCreate.visibility === Visibility.WORKSPACE) { - return shortcut.visibility === "PUBLIC" || shortcut.visibility === "WORKSPACE"; + return shortcut.visibility === Visibility.PUBLIC || shortcut.visibility === Visibility.WORKSPACE; } else { return true; } diff --git a/frontend/web/src/components/CreateShortcutDrawer.tsx b/frontend/web/src/components/CreateShortcutDrawer.tsx index e10cd2f..0efd3c4 100644 --- a/frontend/web/src/components/CreateShortcutDrawer.tsx +++ b/frontend/web/src/components/CreateShortcutDrawer.tsx @@ -16,46 +16,42 @@ import { isUndefined, uniq } from "lodash-es"; import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import { useTranslation } from "react-i18next"; -import { useAppSelector } from "@/stores"; +import useShortcutStore from "@/stores/v1/shortcut"; +import { Visibility } from "@/types/proto/api/v2/common"; +import { Shortcut } from "@/types/proto/api/v2/shortcut_service"; +import { convertVisibilityFromPb } from "@/utils/visibility"; import useLoading from "../hooks/useLoading"; -import { shortcutService } from "../services"; import Icon from "./Icon"; import ResourceNameInput from "./ResourceNameInput"; interface Props { - shortcutId?: ShortcutId; + shortcutId?: number; initialShortcut?: Partial; onClose: () => void; onConfirm?: () => void; } interface State { - shortcutCreate: ShortcutCreate; + shortcutCreate: Shortcut; } -const visibilities: Visibility[] = ["PRIVATE", "WORKSPACE", "PUBLIC"]; - const CreateShortcutDrawer: React.FC = (props: Props) => { const { onClose, onConfirm, shortcutId, initialShortcut } = props; const { t } = useTranslation(); - const { shortcutList } = useAppSelector((state) => state.shortcut); const [state, setState] = useState({ - shortcutCreate: { - name: "", - link: "", - title: "", - description: "", - visibility: "PRIVATE", - tags: [], - openGraphMetadata: { + shortcutCreate: Shortcut.fromPartial({ + visibility: Visibility.PRIVATE, + ogMetadata: { title: "", description: "", image: "", }, ...initialShortcut, - }, + }), }); + const shortcutStore = useShortcutStore(); const [showOpenGraphMetadata, setShowOpenGraphMetadata] = useState(false); + const shortcutList = shortcutStore.getShortcutList(); const [tag, setTag] = useState(""); const tagSuggestions = uniq(shortcutList.map((shortcut) => shortcut.tags).flat()); const isCreating = isUndefined(shortcutId); @@ -64,7 +60,7 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { useEffect(() => { if (shortcutId) { - const shortcut = shortcutService.getShortcutById(shortcutId); + const shortcut = shortcutStore.getShortcutById(shortcutId); if (shortcut) { setState({ ...state, @@ -74,7 +70,7 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { title: shortcut.title, description: shortcut.description, visibility: shortcut.visibility, - openGraphMetadata: shortcut.openGraphMetadata, + ogMetadata: shortcut.ogMetadata, }), }); setTag(shortcut.tags.join(" ")); @@ -121,7 +117,7 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { const handleVisibilityInputChange = (e: React.ChangeEvent) => { setPartialState({ shortcutCreate: Object.assign(state.shortcutCreate, { - visibility: e.target.value, + visibility: Number(e.target.value), }), }); }; @@ -142,8 +138,8 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { const handleOpenGraphMetadataImageChange = (e: React.ChangeEvent) => { setPartialState({ shortcutCreate: Object.assign(state.shortcutCreate, { - openGraphMetadata: { - ...state.shortcutCreate.openGraphMetadata, + ogMetadata: { + ...state.shortcutCreate.ogMetadata, image: e.target.value, }, }), @@ -153,8 +149,8 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { const handleOpenGraphMetadataTitleChange = (e: React.ChangeEvent) => { setPartialState({ shortcutCreate: Object.assign(state.shortcutCreate, { - openGraphMetadata: { - ...state.shortcutCreate.openGraphMetadata, + ogMetadata: { + ...state.shortcutCreate.ogMetadata, title: e.target.value, }, }), @@ -164,8 +160,8 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { const handleOpenGraphMetadataDescriptionChange = (e: React.ChangeEvent) => { setPartialState({ shortcutCreate: Object.assign(state.shortcutCreate, { - openGraphMetadata: { - ...state.shortcutCreate.openGraphMetadata, + ogMetadata: { + ...state.shortcutCreate.ogMetadata, description: e.target.value, }, }), @@ -188,18 +184,13 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { try { if (shortcutId) { - await shortcutService.patchShortcut({ + await shortcutStore.updateShortcut({ + ...state.shortcutCreate, id: shortcutId, - name: state.shortcutCreate.name, - link: state.shortcutCreate.link, - title: state.shortcutCreate.title, - description: state.shortcutCreate.description, - visibility: state.shortcutCreate.visibility, tags: tag.split(" ").filter(Boolean), - openGraphMetadata: state.shortcutCreate.openGraphMetadata, }); } else { - await shortcutService.createShortcut({ + await shortcutStore.createShortcut({ ...state.shortcutCreate, tags: tag.split(" ").filter(Boolean), }); @@ -281,13 +272,13 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { Visibility
- {visibilities.map((visibility) => ( - - ))} + + +

- {t(`shortcut.visibility.${state.shortcutCreate.visibility.toLowerCase()}.description`)} + {t(`shortcut.visibility.${convertVisibilityFromPb(state.shortcutCreate.visibility).toLowerCase()}.description`)}

More @@ -316,7 +307,7 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { type="text" placeholder="https://the.link.to/the/image.png" size="sm" - value={state.shortcutCreate.openGraphMetadata.image} + value={state.shortcutCreate.ogMetadata?.image} onChange={handleOpenGraphMetadataImageChange} /> @@ -327,7 +318,7 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { type="text" placeholder="Slash - An open source, self-hosted bookmarks and link sharing platform" size="sm" - value={state.shortcutCreate.openGraphMetadata.title} + value={state.shortcutCreate.ogMetadata?.title} onChange={handleOpenGraphMetadataTitleChange} /> @@ -338,7 +329,7 @@ const CreateShortcutDrawer: React.FC = (props: Props) => { placeholder="An open source, self-hosted bookmarks and link sharing platform." size="sm" maxRows={3} - value={state.shortcutCreate.openGraphMetadata.description} + value={state.shortcutCreate.ogMetadata?.description} onChange={handleOpenGraphMetadataDescriptionChange} /> diff --git a/frontend/web/src/components/FilterView.tsx b/frontend/web/src/components/FilterView.tsx index ff5ab17..c5d15dd 100644 --- a/frontend/web/src/components/FilterView.tsx +++ b/frontend/web/src/components/FilterView.tsx @@ -1,4 +1,5 @@ import { useTranslation } from "react-i18next"; +import { convertVisibilityFromPb } from "@/utils/visibility"; import useViewStore from "../stores/v1/view"; import Icon from "./Icon"; import VisibilityIcon from "./VisibilityIcon"; @@ -32,7 +33,7 @@ const FilterView = () => { onClick={() => viewStore.setFilter({ visibility: undefined })} > - {t(`shortcut.visibility.${filter.visibility.toLowerCase()}.self`)} + {t(`shortcut.visibility.${convertVisibilityFromPb(filter.visibility).toLowerCase()}.self`)} )} diff --git a/frontend/web/src/components/GenerateQRCodeDialog.tsx b/frontend/web/src/components/GenerateQRCodeDialog.tsx index 427ca05..519a1bb 100644 --- a/frontend/web/src/components/GenerateQRCodeDialog.tsx +++ b/frontend/web/src/components/GenerateQRCodeDialog.tsx @@ -3,6 +3,7 @@ import { QRCodeCanvas } from "qrcode.react"; import { useRef } from "react"; import { toast } from "react-hot-toast"; import { useTranslation } from "react-i18next"; +import { Shortcut } from "@/types/proto/api/v2/shortcut_service"; import { absolutifyLink } from "../helpers/utils"; import Icon from "./Icon"; diff --git a/frontend/web/src/components/ShortcutActionsDropdown.tsx b/frontend/web/src/components/ShortcutActionsDropdown.tsx index 0d4b944..482e2ea 100644 --- a/frontend/web/src/components/ShortcutActionsDropdown.tsx +++ b/frontend/web/src/components/ShortcutActionsDropdown.tsx @@ -1,8 +1,9 @@ import { useState } from "react"; import { useTranslation } from "react-i18next"; import useNavigateTo from "@/hooks/useNavigateTo"; +import useShortcutStore from "@/stores/v1/shortcut"; +import { Shortcut } from "@/types/proto/api/v2/shortcut_service"; import { Role } from "@/types/proto/api/v2/user_service"; -import { shortcutService } from "../services"; import useUserStore from "../stores/v1/user"; import { showCommonDialog } from "./Alert"; import CreateShortcutDrawer from "./CreateShortcutDrawer"; @@ -18,6 +19,7 @@ const ShortcutActionsDropdown = (props: Props) => { const { shortcut } = props; const { t } = useTranslation(); const navigateTo = useNavigateTo(); + const shortcutStore = useShortcutStore(); const currentUser = useUserStore().getCurrentUser(); const [showEditDrawer, setShowEditDrawer] = useState(false); const [showQRCodeDialog, setShowQRCodeDialog] = useState(false); @@ -29,7 +31,7 @@ const ShortcutActionsDropdown = (props: Props) => { content: `Are you sure to delete shortcut \`${shortcut.name}\`? You cannot undo this action.`, style: "danger", onConfirm: async () => { - await shortcutService.deleteShortcutById(shortcut.id); + await shortcutStore.deleteShortcut(shortcut.id); }, }); }; diff --git a/frontend/web/src/components/ShortcutCard.tsx b/frontend/web/src/components/ShortcutCard.tsx index 1d49422..a0b5a5f 100644 --- a/frontend/web/src/components/ShortcutCard.tsx +++ b/frontend/web/src/components/ShortcutCard.tsx @@ -4,6 +4,8 @@ import copy from "copy-to-clipboard"; import toast from "react-hot-toast"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; +import { Shortcut } from "@/types/proto/api/v2/shortcut_service"; +import { convertVisibilityFromPb } from "@/utils/visibility"; import { absolutifyLink, getFaviconWithGoogleS2 } from "../helpers/utils"; import useViewStore from "../stores/v1/view"; import Icon from "./Icon"; @@ -102,13 +104,18 @@ const ShortcutCard = (props: Props) => { {shortcut.tags.length === 0 && No tags}
- +
viewStore.setFilter({ visibility: shortcut.visibility })} > - {t(`shortcut.visibility.${shortcut.visibility.toLowerCase()}.self`)} + {t(`shortcut.visibility.${convertVisibilityFromPb(shortcut.visibility).toLowerCase()}.self`)}
@@ -117,7 +124,7 @@ const ShortcutCard = (props: Props) => { className="w-auto px-2 leading-6 flex flex-row justify-start items-center flex-nowrap whitespace-nowrap border rounded-full cursor-pointer text-gray-500 dark:text-gray-400 text-sm dark:border-zinc-700" > - {t("shortcut.visits", { count: shortcut.view })} + {t("shortcut.visits", { count: shortcut.viewCount })}
diff --git a/frontend/web/src/components/ShortcutView.tsx b/frontend/web/src/components/ShortcutView.tsx index 7bd80b0..672cd03 100644 --- a/frontend/web/src/components/ShortcutView.tsx +++ b/frontend/web/src/components/ShortcutView.tsx @@ -1,5 +1,6 @@ import classNames from "classnames"; import { Link } from "react-router-dom"; +import { Shortcut } from "@/types/proto/api/v2/shortcut_service"; import { getFaviconWithGoogleS2 } from "../helpers/utils"; import Icon from "./Icon"; import ShortcutActionsDropdown from "./ShortcutActionsDropdown"; diff --git a/frontend/web/src/components/ShortcutsContainer.tsx b/frontend/web/src/components/ShortcutsContainer.tsx index eaccedd..7e0213b 100644 --- a/frontend/web/src/components/ShortcutsContainer.tsx +++ b/frontend/web/src/components/ShortcutsContainer.tsx @@ -1,5 +1,6 @@ import classNames from "classnames"; import useNavigateTo from "@/hooks/useNavigateTo"; +import { Shortcut } from "@/types/proto/api/v2/shortcut_service"; import useViewStore from "../stores/v1/view"; import ShortcutCard from "./ShortcutCard"; import ShortcutView from "./ShortcutView"; diff --git a/frontend/web/src/components/ShortcutsNavigator.tsx b/frontend/web/src/components/ShortcutsNavigator.tsx index 58df272..27986f5 100644 --- a/frontend/web/src/components/ShortcutsNavigator.tsx +++ b/frontend/web/src/components/ShortcutsNavigator.tsx @@ -1,13 +1,13 @@ import classNames from "classnames"; import { useTranslation } from "react-i18next"; -import { useAppSelector } from "../stores"; +import useShortcutStore from "@/stores/v1/shortcut"; import useViewStore from "../stores/v1/view"; import Icon from "./Icon"; const ShortcutsNavigator = () => { const { t } = useTranslation(); const viewStore = useViewStore(); - const { shortcutList } = useAppSelector((state) => state.shortcut); + const shortcutList = useShortcutStore().getShortcutList(); const tags = shortcutList.map((shortcut) => shortcut.tags).flat(); const currentTab = viewStore.filter.tab || `tab:all`; const sortedTagMap = sortTags(tags); diff --git a/frontend/web/src/components/VisibilityIcon.tsx b/frontend/web/src/components/VisibilityIcon.tsx index 183d4ff..40bddc1 100644 --- a/frontend/web/src/components/VisibilityIcon.tsx +++ b/frontend/web/src/components/VisibilityIcon.tsx @@ -1,3 +1,4 @@ +import { Visibility } from "@/types/proto/api/v2/common"; import Icon from "./Icon"; interface Props { @@ -7,11 +8,11 @@ interface Props { const VisibilityIcon = (props: Props) => { const { visibility, className } = props; - if (visibility === "PRIVATE") { + if (visibility === Visibility.PRIVATE) { return ; - } else if (visibility === "WORKSPACE") { + } else if (visibility === Visibility.WORKSPACE) { return ; - } else if (visibility === "PUBLIC") { + } else if (visibility === Visibility.PUBLIC) { return ; } return null; diff --git a/frontend/web/src/helpers/api.ts b/frontend/web/src/helpers/api.ts index f00a2ee..035f199 100644 --- a/frontend/web/src/helpers/api.ts +++ b/frontend/web/src/helpers/api.ts @@ -19,30 +19,6 @@ export function signout() { return axios.post("/api/v1/auth/logout"); } -export function getShortcutList(shortcutFind?: ShortcutFind) { - const queryList = []; - if (shortcutFind?.tag) { - queryList.push(`tag=${shortcutFind.tag}`); - } - return axios.get(`/api/v1/shortcut?${queryList.join("&")}`); -} - -export function getShortcutById(id: number) { - return axios.get(`/api/v1/shortcut/${id}`); -} - -export function createShortcut(shortcutCreate: ShortcutCreate) { - return axios.post("/api/v1/shortcut", shortcutCreate); -} - -export function getShortcutAnalytics(shortcutId: ShortcutId) { +export function getShortcutAnalytics(shortcutId: number) { return axios.get(`/api/v1/shortcut/${shortcutId}/analytics`); } - -export function patchShortcut(shortcutPatch: ShortcutPatch) { - return axios.patch(`/api/v1/shortcut/${shortcutPatch.id}`, shortcutPatch); -} - -export function deleteShortcutById(shortcutId: ShortcutId) { - return axios.delete(`/api/v1/shortcut/${shortcutId}`); -} diff --git a/frontend/web/src/main.tsx b/frontend/web/src/main.tsx index c9f54c9..786c435 100644 --- a/frontend/web/src/main.tsx +++ b/frontend/web/src/main.tsx @@ -1,22 +1,18 @@ import { CssVarsProvider } from "@mui/joy"; import { createRoot } from "react-dom/client"; import { Toaster } from "react-hot-toast"; -import { Provider } from "react-redux"; import { RouterProvider } from "react-router-dom"; import "./css/index.css"; import "./css/joy-ui.css"; import "./i18n"; import router from "./routers"; -import store from "./stores"; const container = document.getElementById("root"); const root = createRoot(container as HTMLElement); root.render( - - - - - - + + + + ); diff --git a/frontend/web/src/pages/CollectionDashboard.tsx b/frontend/web/src/pages/CollectionDashboard.tsx index 2277127..8d970aa 100644 --- a/frontend/web/src/pages/CollectionDashboard.tsx +++ b/frontend/web/src/pages/CollectionDashboard.tsx @@ -3,8 +3,8 @@ import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import CollectionView from "@/components/CollectionView"; import CreateCollectionDrawer from "@/components/CreateCollectionDrawer"; -import { shortcutService } from "@/services"; import useCollectionStore from "@/stores/v1/collection"; +import useShortcutStore from "@/stores/v1/shortcut"; import FilterView from "../components/FilterView"; import Icon from "../components/Icon"; import useLoading from "../hooks/useLoading"; @@ -16,6 +16,7 @@ interface State { const CollectionDashboard: React.FC = () => { const { t } = useTranslation(); const loadingState = useLoading(); + const shortcutStore = useShortcutStore(); const collectionStore = useCollectionStore(); const [state, setState] = useState({ showCreateCollectionDrawer: false, @@ -30,7 +31,7 @@ const CollectionDashboard: React.FC = () => { }); useEffect(() => { - Promise.all([shortcutService.getMyAllShortcuts(), collectionStore.fetchCollectionList()]).finally(() => { + Promise.all([shortcutStore.fetchShortcutList(), collectionStore.fetchCollectionList()]).finally(() => { loadingState.setFinish(); }); }, []); diff --git a/frontend/web/src/pages/CollectionSpace.tsx b/frontend/web/src/pages/CollectionSpace.tsx index 2827ece..23aa1a7 100644 --- a/frontend/web/src/pages/CollectionSpace.tsx +++ b/frontend/web/src/pages/CollectionSpace.tsx @@ -12,7 +12,6 @@ import useShortcutStore from "@/stores/v1/shortcut"; import useUserStore from "@/stores/v1/user"; import { Collection } from "@/types/proto/api/v2/collection_service"; import { Shortcut } from "@/types/proto/api/v2/shortcut_service"; -import { convertShortcutFromPb } from "@/utils/shortcut"; const CollectionSpace = () => { const { collectionName } = useParams(); @@ -90,7 +89,7 @@ const CollectionSpace = () => { : "sm:border-transparent dark:sm:border-transparent" )} key={shortcut.name} - shortcut={convertShortcutFromPb(shortcut)} + shortcut={shortcut} alwaysShowLink={!sm} onClick={() => handleShortcutClick(shortcut)} /> diff --git a/frontend/web/src/pages/Home.tsx b/frontend/web/src/pages/Home.tsx index b977e70..620dd14 100644 --- a/frontend/web/src/pages/Home.tsx +++ b/frontend/web/src/pages/Home.tsx @@ -1,6 +1,7 @@ import { Button, Input } from "@mui/joy"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; +import useShortcutStore from "@/stores/v1/shortcut"; import CreateShortcutDrawer from "../components/CreateShortcutDrawer"; import FilterView from "../components/FilterView"; import Icon from "../components/Icon"; @@ -8,8 +9,6 @@ import ShortcutsContainer from "../components/ShortcutsContainer"; import ShortcutsNavigator from "../components/ShortcutsNavigator"; import ViewSetting from "../components/ViewSetting"; import useLoading from "../hooks/useLoading"; -import { shortcutService } from "../services"; -import { useAppSelector } from "../stores"; import useUserStore from "../stores/v1/user"; import useViewStore, { getFilteredShortcutList, getOrderedShortcutList } from "../stores/v1/view"; @@ -21,8 +20,9 @@ const Home: React.FC = () => { const { t } = useTranslation(); const loadingState = useLoading(); const currentUser = useUserStore().getCurrentUser(); + const shortcutStore = useShortcutStore(); const viewStore = useViewStore(); - const { shortcutList } = useAppSelector((state) => state.shortcut); + const shortcutList = shortcutStore.getShortcutList(); const [state, setState] = useState({ showCreateShortcutDrawer: false, }); @@ -31,7 +31,7 @@ const Home: React.FC = () => { const orderedShortcutList = getOrderedShortcutList(filteredShortcutList, viewStore.order); useEffect(() => { - Promise.all([shortcutService.getMyAllShortcuts()]).finally(() => { + Promise.all([shortcutStore.fetchShortcutList()]).finally(() => { loadingState.setFinish(); }); }, []); diff --git a/frontend/web/src/pages/ShortcutDetail.tsx b/frontend/web/src/pages/ShortcutDetail.tsx index fc5cdea..4325ff8 100644 --- a/frontend/web/src/pages/ShortcutDetail.tsx +++ b/frontend/web/src/pages/ShortcutDetail.tsx @@ -1,12 +1,16 @@ import { Tooltip } from "@mui/joy"; import classNames from "classnames"; import copy from "copy-to-clipboard"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import toast from "react-hot-toast"; import { useTranslation } from "react-i18next"; -import { useLoaderData } from "react-router-dom"; +import { useParams } from "react-router-dom"; +import useLoading from "@/hooks/useLoading"; import useNavigateTo from "@/hooks/useNavigateTo"; +import useShortcutStore from "@/stores/v1/shortcut"; +import { Shortcut } from "@/types/proto/api/v2/shortcut_service"; import { Role } from "@/types/proto/api/v2/user_service"; +import { convertVisibilityFromPb } from "@/utils/visibility"; import { showCommonDialog } from "../components/Alert"; import AnalyticsView from "../components/AnalyticsView"; import CreateShortcutDrawer from "../components/CreateShortcutDrawer"; @@ -15,7 +19,6 @@ import Icon from "../components/Icon"; import VisibilityIcon from "../components/VisibilityIcon"; import Dropdown from "../components/common/Dropdown"; import { absolutifyLink, getFaviconWithGoogleS2 } from "../helpers/utils"; -import { shortcutService } from "../services"; import useUserStore from "../stores/v1/user"; interface State { @@ -24,18 +27,35 @@ interface State { const ShortcutDetail = () => { const { t } = useTranslation(); + const params = useParams(); const navigateTo = useNavigateTo(); - const shortcutId = (useLoaderData() as Shortcut).id; - const shortcut = shortcutService.getShortcutById(shortcutId) as Shortcut; + const shortcutId = Number(params.shortcutId); + const shortcutStore = useShortcutStore(); + const userStore = useUserStore(); + const shortcut = shortcutStore.getShortcutById(shortcutId); const currentUser = useUserStore().getCurrentUser(); const [state, setState] = useState({ showEditDrawer: false, }); const [showQRCodeDialog, setShowQRCodeDialog] = useState(false); + const loadingState = useLoading(true); + const creator = userStore.getUserById(shortcut.creatorId); const havePermission = currentUser.role === Role.ADMIN || shortcut.creatorId === currentUser.id; const shortcutLink = absolutifyLink(`/s/${shortcut.name}`); const favicon = getFaviconWithGoogleS2(shortcut.link); + useEffect(() => { + (async () => { + const shortcut = await shortcutStore.getOrFetchShortcutById(shortcutId); + await userStore.getOrFetchUserById(shortcut.creatorId); + loadingState.setFinish(); + })(); + }, [shortcutId]); + + if (loadingState.isLoading) { + return null; + } + const handleCopyButtonClick = () => { copy(shortcutLink); toast.success("Shortcut link copied to clipboard."); @@ -47,7 +67,7 @@ const ShortcutDetail = () => { content: `Are you sure to delete shortcut \`${shortcut.name}\`? You cannot undo this action.`, style: "danger", onConfirm: async () => { - await shortcutService.deleteShortcutById(shortcut.id); + await shortcutStore.deleteShortcut(shortcut.id); navigateTo("/", { replace: true, }); @@ -151,19 +171,24 @@ const ShortcutDetail = () => {
- {shortcut.creator.nickname} + {creator.nickname}
- +
- {t(`shortcut.visibility.${shortcut.visibility.toLowerCase()}.self`)} + {t(`shortcut.visibility.${convertVisibilityFromPb(shortcut.visibility).toLowerCase()}.self`)}
- {shortcut.view} visits + {shortcut.viewCount} visits
diff --git a/frontend/web/src/routers/index.tsx b/frontend/web/src/routers/index.tsx index f32a457..2e3b0e1 100644 --- a/frontend/web/src/routers/index.tsx +++ b/frontend/web/src/routers/index.tsx @@ -11,7 +11,6 @@ import App from "../App"; import Root from "../layouts/Root"; import Home from "../pages/Home"; import ShortcutDetail from "../pages/ShortcutDetail"; -import { shortcutService } from "../services"; const router = createBrowserRouter([ { @@ -41,10 +40,6 @@ const router = createBrowserRouter([ { path: "/shortcut/:shortcutId", element: , - loader: async ({ params }) => { - const shortcut = await shortcutService.getOrFetchShortcutById(Number(params.shortcutId)); - return shortcut; - }, }, { path: "/setting/general", diff --git a/frontend/web/src/services/index.ts b/frontend/web/src/services/index.ts deleted file mode 100644 index 3e4e9c7..0000000 --- a/frontend/web/src/services/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import shortcutService from "./shortcutService"; - -export { shortcutService }; diff --git a/frontend/web/src/services/shortcutService.ts b/frontend/web/src/services/shortcutService.ts deleted file mode 100644 index 020cb4a..0000000 --- a/frontend/web/src/services/shortcutService.ts +++ /dev/null @@ -1,64 +0,0 @@ -import * as api from "../helpers/api"; -import store from "../stores"; -import { createShortcut, deleteShortcut, patchShortcut, setShortcuts } from "../stores/modules/shortcut"; - -const convertResponseModelShortcut = (shortcut: Shortcut): Shortcut => { - return { - ...shortcut, - createdTs: shortcut.createdTs * 1000, - updatedTs: shortcut.updatedTs * 1000, - }; -}; - -const shortcutService = { - getState: () => { - return store.getState().shortcut; - }, - - getMyAllShortcuts: async () => { - const data = (await api.getShortcutList()).data; - const shortcuts = data.map((s) => convertResponseModelShortcut(s)); - store.dispatch(setShortcuts(shortcuts)); - }, - - getShortcutById: (id: ShortcutId) => { - for (const shortcut of shortcutService.getState().shortcutList) { - if (shortcut.id === id) { - return shortcut; - } - } - return null; - }, - - getOrFetchShortcutById: async (id: ShortcutId) => { - for (const shortcut of shortcutService.getState().shortcutList) { - if (shortcut.id === id) { - return shortcut; - } - } - - const data = (await api.getShortcutById(id)).data; - const shortcut = convertResponseModelShortcut(data); - store.dispatch(createShortcut(shortcut)); - return shortcut; - }, - - createShortcut: async (shortcutCreate: ShortcutCreate) => { - const data = (await api.createShortcut(shortcutCreate)).data; - const shortcut = convertResponseModelShortcut(data); - store.dispatch(createShortcut(shortcut)); - }, - - patchShortcut: async (shortcutPatch: ShortcutPatch) => { - const data = (await api.patchShortcut(shortcutPatch)).data; - const shortcut = convertResponseModelShortcut(data); - store.dispatch(patchShortcut(shortcut)); - }, - - deleteShortcutById: async (shortcutId: ShortcutId) => { - await api.deleteShortcutById(shortcutId); - store.dispatch(deleteShortcut(shortcutId)); - }, -}; - -export default shortcutService; diff --git a/frontend/web/src/stores/index.ts b/frontend/web/src/stores/index.ts deleted file mode 100644 index 2febc72..0000000 --- a/frontend/web/src/stores/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { configureStore } from "@reduxjs/toolkit"; -import { TypedUseSelectorHook, useSelector } from "react-redux"; -import shortcutReducer from "./modules/shortcut"; - -const store = configureStore({ - reducer: { - shortcut: shortcutReducer, - }, -}); - -type AppState = ReturnType; - -export const useAppSelector: TypedUseSelectorHook = useSelector; - -export default store; diff --git a/frontend/web/src/stores/modules/shortcut.ts b/frontend/web/src/stores/modules/shortcut.ts deleted file mode 100644 index 2992ea7..0000000 --- a/frontend/web/src/stores/modules/shortcut.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { createSlice, PayloadAction } from "@reduxjs/toolkit"; - -interface State { - shortcutList: Shortcut[]; -} - -const shortcutSlice = createSlice({ - name: "shortcut", - initialState: { - shortcutList: [], - } as State, - reducers: { - setShortcuts: (state, action: PayloadAction) => { - return { - ...state, - shortcutList: action.payload, - }; - }, - createShortcut: (state, action: PayloadAction) => { - return { - ...state, - shortcutList: state.shortcutList.concat(action.payload).sort((a, b) => b.createdTs - a.createdTs), - }; - }, - patchShortcut: (state, action: PayloadAction>) => { - return { - ...state, - shortcutList: state.shortcutList.map((s) => { - if (s.id === action.payload.id) { - return { - ...s, - ...action.payload, - }; - } else { - return s; - } - }), - }; - }, - deleteShortcut: (state, action: PayloadAction) => { - return { - ...state, - shortcutList: [...state.shortcutList].filter((shortcut) => shortcut.id !== action.payload), - }; - }, - }, -}); - -export const { setShortcuts, createShortcut, patchShortcut, deleteShortcut } = shortcutSlice.actions; - -export default shortcutSlice.reducer; diff --git a/frontend/web/src/stores/v1/collection.ts b/frontend/web/src/stores/v1/collection.ts index 8cf9f21..c2ebcdd 100644 --- a/frontend/web/src/stores/v1/collection.ts +++ b/frontend/web/src/stores/v1/collection.ts @@ -84,8 +84,6 @@ const useCollectionStore = create()((set, get) => ({ throw new Error("Collection not found"); } - console.log("updatedCollection", updatedCollection); - const collectionMap = get().collectionMapById; collectionMap[updatedCollection.id] = updatedCollection; set(collectionMap); diff --git a/frontend/web/src/stores/v1/shortcut.ts b/frontend/web/src/stores/v1/shortcut.ts index dda355f..f45b588 100644 --- a/frontend/web/src/stores/v1/shortcut.ts +++ b/frontend/web/src/stores/v1/shortcut.ts @@ -3,11 +3,14 @@ import { shortcutServiceClient } from "@/grpcweb"; import { Shortcut } from "@/types/proto/api/v2/shortcut_service"; interface ShortcutState { - shortcutMapById: Record; + shortcutMapById: Record; fetchShortcutList: () => Promise; - getOrFetchShortcutById: (id: ShortcutId) => Promise; - getShortcutById: (id: ShortcutId) => Shortcut; + getOrFetchShortcutById: (id: number) => Promise; + getShortcutById: (id: number) => Shortcut; getShortcutList: () => Shortcut[]; + createShortcut: (shortcut: Shortcut) => Promise; + updateShortcut: (shortcut: Partial) => Promise; + deleteShortcut: (id: number) => Promise; } const useShortcutStore = create()((set, get) => ({ @@ -21,7 +24,7 @@ const useShortcutStore = create()((set, get) => ({ set(shortcutMap); return shortcuts; }, - getOrFetchShortcutById: async (id: ShortcutId) => { + getOrFetchShortcutById: async (id: number) => { const shortcutMap = get().shortcutMapById; if (shortcutMap[id]) { return shortcutMap[id] as Shortcut; @@ -38,13 +41,50 @@ const useShortcutStore = create()((set, get) => ({ set(shortcutMap); return shortcut; }, - getShortcutById: (id: ShortcutId) => { + getShortcutById: (id: number) => { const shortcutMap = get().shortcutMapById; - return shortcutMap[id] as Shortcut; + return shortcutMap[id] || unknownShortcut; }, getShortcutList: () => { return Object.values(get().shortcutMapById); }, + createShortcut: async (shortcut: Shortcut) => { + const { shortcut: createdShortcut } = await shortcutServiceClient.createShortcut({ + shortcut: shortcut, + }); + if (!createdShortcut) { + throw new Error(`Failed to create shortcut`); + } + const shortcutMap = get().shortcutMapById; + shortcutMap[createdShortcut.id] = createdShortcut; + set(shortcutMap); + return createdShortcut; + }, + updateShortcut: async (shortcut: Partial) => { + const { shortcut: updatedShortcut } = await shortcutServiceClient.updateShortcut({ + shortcut: shortcut, + }); + if (!updatedShortcut) { + throw new Error(`Failed to update shortcut`); + } + const shortcutMap = get().shortcutMapById; + shortcutMap[updatedShortcut.id] = updatedShortcut; + set(shortcutMap); + return updatedShortcut; + }, + deleteShortcut: async (id: number) => { + await shortcutServiceClient.deleteShortcut({ + id: id, + }); + const shortcutMap = get().shortcutMapById; + delete shortcutMap[id]; + set(shortcutMap); + }, })); +const unknownShortcut: Shortcut = Shortcut.fromPartial({ + id: -1, + name: "Unknown", +}); + export default useShortcutStore; diff --git a/frontend/web/src/stores/v1/user.ts b/frontend/web/src/stores/v1/user.ts index e270348..770d08c 100644 --- a/frontend/web/src/stores/v1/user.ts +++ b/frontend/web/src/stores/v1/user.ts @@ -103,7 +103,7 @@ const useUserStore = create()((set, get) => ({ }, getUserById: (id: number) => { const userMap = get().userMapById; - return userMap[id] as User; + return userMap[id] || unknownUser; }, getCurrentUser: () => { const userMap = get().userMapById; @@ -148,4 +148,10 @@ const useUserStore = create()((set, get) => ({ }, })); +const unknownUser: User = User.fromPartial({ + id: -1, + email: "Unknown", + nickname: "Unknown", +}); + export default useUserStore; diff --git a/frontend/web/src/stores/v1/view.ts b/frontend/web/src/stores/v1/view.ts index 07fd7f2..274a145 100644 --- a/frontend/web/src/stores/v1/view.ts +++ b/frontend/web/src/stores/v1/view.ts @@ -1,5 +1,7 @@ import { create } from "zustand"; import { persist } from "zustand/middleware"; +import { Visibility } from "@/types/proto/api/v2/common"; +import { Shortcut } from "@/types/proto/api/v2/shortcut_service"; import { User } from "@/types/proto/api/v2/user_service"; export interface Filter { @@ -102,11 +104,15 @@ export const getOrderedShortcutList = (shortcutList: Shortcut[], order: Order) = if (field === "name") { return direction === "asc" ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name); } else if (field === "createdTs") { - return direction === "asc" ? a.createdTs - b.createdTs : b.createdTs - a.createdTs; + return direction === "asc" + ? getDateTimestamp(a.createdTime) - getDateTimestamp(b.createdTime) + : getDateTimestamp(b.createdTime) - getDateTimestamp(a.createdTime); } else if (field === "updatedTs") { - return direction === "asc" ? a.updatedTs - b.updatedTs : b.updatedTs - a.updatedTs; + return direction === "asc" + ? getDateTimestamp(a.updatedTime) - getDateTimestamp(b.updatedTime) + : getDateTimestamp(b.updatedTime) - getDateTimestamp(a.updatedTime); } else if (field === "view") { - return direction === "asc" ? a.view - b.view : b.view - a.view; + return direction === "asc" ? a.viewCount - b.viewCount : b.viewCount - a.viewCount; } else { return 0; } @@ -114,4 +120,8 @@ export const getOrderedShortcutList = (shortcutList: Shortcut[], order: Order) = return orderedShortcutList; }; +const getDateTimestamp = (date: Date = new Date()) => { + return new Date(date).getTime(); +}; + export default useViewStore; diff --git a/frontend/web/src/types/modules/common.d.ts b/frontend/web/src/types/modules/common.d.ts deleted file mode 100644 index 4089da3..0000000 --- a/frontend/web/src/types/modules/common.d.ts +++ /dev/null @@ -1 +0,0 @@ -type RowStatus = "NORMAL" | "ARCHIVED"; diff --git a/frontend/web/src/types/modules/shortcut.d.ts b/frontend/web/src/types/modules/shortcut.d.ts deleted file mode 100644 index 6182891..0000000 --- a/frontend/web/src/types/modules/shortcut.d.ts +++ /dev/null @@ -1,54 +0,0 @@ -type ShortcutId = number; - -type Visibility = "PRIVATE" | "WORKSPACE" | "PUBLIC"; - -interface OpenGraphMetadata { - title: string; - description: string; - image: string; -} - -interface Shortcut { - id: ShortcutId; - - creatorId: number; - creator: User; - createdTs: TimeStamp; - updatedTs: TimeStamp; - rowStatus: RowStatus; - - name: string; - link: string; - title: string; - description: string; - visibility: Visibility; - tags: string[]; - openGraphMetadata: OpenGraphMetadata; - view: number; -} - -interface ShortcutCreate { - name: string; - link: string; - title: string; - description: string; - visibility: Visibility; - tags: string[]; - openGraphMetadata: OpenGraphMetadata; -} - -interface ShortcutPatch { - id: ShortcutId; - - name?: string; - link?: string; - title?: string; - description?: string; - visibility?: Visibility; - tags?: string[]; - openGraphMetadata?: OpenGraphMetadata; -} - -interface ShortcutFind { - tag?: string; -} diff --git a/frontend/web/src/utils/shortcut.ts b/frontend/web/src/utils/shortcut.ts deleted file mode 100644 index d7729d1..0000000 --- a/frontend/web/src/utils/shortcut.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Shortcut as ShortcutPb } from "@/types/proto/api/v2/shortcut_service"; - -export const convertShortcutFromPb = (shortcutMessage: ShortcutPb): Shortcut => { - return { - id: shortcutMessage.id, - creatorId: shortcutMessage.creatorId, - createdTs: shortcutMessage.createdTime?.getTime() || 0, - updatedTs: shortcutMessage.updatedTime?.getTime() || 0, - name: shortcutMessage.name, - link: shortcutMessage.link, - title: shortcutMessage.title, - description: shortcutMessage.description, - tags: shortcutMessage.tags, - } as Shortcut; -};