diff --git a/frontend/eslint.config.js b/frontend/eslint.config.js index 0fe9f982..fc3a1318 100644 --- a/frontend/eslint.config.js +++ b/frontend/eslint.config.js @@ -21,7 +21,6 @@ export default tseslint.config( ], files: ["**/*.{ts,tsx}"], languageOptions: { - ecmaVersion: 2024, globals: globals.browser, parserOptions: { projectService: true, diff --git a/frontend/package.json b/frontend/package.json index 93bbe316..2ee7ab91 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -43,12 +43,12 @@ "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^4.4.1", "eslint": "^9.39.4", - "eslint-plugin-react-dom": "^2.7.2", + "eslint-plugin-react-dom": "^5.9.0", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", - "eslint-plugin-react-x": "^1.49.0", + "eslint-plugin-react-x": "^5.9.0", "globals": "^15.15.0", - "typescript": "~5.8.3", + "typescript": "~6.0.3", "typescript-eslint": "^8.32.1", "vite": "^6.4.3", "vite-tsconfig-paths": "^6.1.1" diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index fd4029cf..60108be3 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -49,7 +49,7 @@ importers: version: 0.9.2 '@hey-api/client-axios': specifier: ^0.7.1 - version: 0.7.1(@hey-api/openapi-ts@0.66.7(typescript@5.8.3))(axios@1.17.0) + version: 0.7.1(@hey-api/openapi-ts@0.66.7(typescript@6.0.3))(axios@1.17.0) '@tanstack/react-form': specifier: ^1.28.5 version: 1.33.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) @@ -89,16 +89,16 @@ importers: version: 9.39.4 '@hey-api/openapi-ts': specifier: ^0.66.7 - version: 0.66.7(typescript@5.8.3) + version: 0.66.7(typescript@6.0.3) '@stylistic/eslint-plugin': specifier: ^5.6.1 version: 5.10.0(eslint@9.39.4(jiti@2.7.0)) '@tanstack/eslint-plugin-query': specifier: ^5.74.7 - version: 5.101.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + version: 5.101.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) '@tanstack/eslint-plugin-router': specifier: ^1.155.0 - version: 1.162.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + version: 1.162.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) '@tanstack/react-router-devtools': specifier: ^1.120.3 version: 1.167.0(@tanstack/react-router@1.170.15(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@tanstack/router-core@1.171.13)(csstype@3.2.3)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) @@ -118,8 +118,8 @@ importers: specifier: ^9.39.4 version: 9.39.4(jiti@2.7.0) eslint-plugin-react-dom: - specifier: ^2.7.2 - version: 2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + specifier: ^5.9.0 + version: 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) eslint-plugin-react-hooks: specifier: ^5.2.0 version: 5.2.0(eslint@9.39.4(jiti@2.7.0)) @@ -127,23 +127,23 @@ importers: specifier: ^0.4.20 version: 0.4.26(eslint@9.39.4(jiti@2.7.0)) eslint-plugin-react-x: - specifier: ^1.49.0 - version: 1.53.1(eslint@9.39.4(jiti@2.7.0))(ts-api-utils@2.5.0(typescript@5.8.3))(typescript@5.8.3) + specifier: ^5.9.0 + version: 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) globals: specifier: ^15.15.0 version: 15.15.0 typescript: - specifier: ~5.8.3 - version: 5.8.3 + specifier: ~6.0.3 + version: 6.0.3 typescript-eslint: specifier: ^8.32.1 - version: 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + version: 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) vite: specifier: ^6.4.3 version: 6.4.3(jiti@2.7.0) vite-tsconfig-paths: specifier: ^6.1.1 - version: 6.1.1(typescript@5.8.3)(vite@6.4.3(jiti@2.7.0)) + version: 6.1.1(typescript@6.0.3)(vite@6.4.3(jiti@2.7.0)) packages: @@ -456,61 +456,47 @@ packages: resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint-react/ast@1.53.1': - resolution: {integrity: sha512-qvUC99ewtriJp9quVEOvZ6+RHcsMLfVQ0OhZ4/LupZUDhjW7GiX1dxJsFaxHdJ9rLNLhQyLSPmbAToeqUrSruQ==} - engines: {node: '>=18.18.0'} - - '@eslint-react/ast@2.13.0': - resolution: {integrity: sha512-43+5gmqV3MpatTzKnu/V2i/jXjmepvwhrb9MaGQvnXHQgq9J7/C7VVCCcwp6Rvp2QHAFquAAdvQDSL8IueTpeA==} - engines: {node: '>=20.19.0'} + '@eslint-react/ast@5.9.0': + resolution: {integrity: sha512-D5DmbsEGYYmHOC2J68BRC2iJhYsD4K0x8mllgB08SeSQ0T/nP2BRogg/ohn5ZeRMb87ZDqN6NtGR7G7qTwgOSw==} + engines: {node: '>=22.0.0'} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@eslint-react/core@1.53.1': - resolution: {integrity: sha512-8prroos5/Uvvh8Tjl1HHCpq4HWD3hV9tYkm7uXgKA6kqj0jHlgRcQzuO6ZPP7feBcK3uOeug7xrq03BuG8QKCA==} - engines: {node: '>=18.18.0'} + eslint: '*' + typescript: '*' - '@eslint-react/core@2.13.0': - resolution: {integrity: sha512-m62XDzkf1hpzW4sBc7uh7CT+8rBG2xz/itSADuEntlsg4YA7Jhb8hjU6VHf3wRFDwyfx5VnbV209sbJ7Azey0Q==} - engines: {node: '>=20.19.0'} + '@eslint-react/core@5.9.0': + resolution: {integrity: sha512-GzARSlLTJT3FY9sUO9bYLoFtgiuUoNKzVv68oJkjAIembiu/6s1vyjs/I/1PEt+pEU6eu5hPjKHJXzd4boSDmQ==} + engines: {node: '>=22.0.0'} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@eslint-react/eff@1.53.1': - resolution: {integrity: sha512-uq20lPRAmsWRjIZm+mAV/2kZsU2nDqn5IJslxGWe3Vfdw23hoyhEw3S1KKlxbftwbTvsZjKvVP0iw3bZo/NUpg==} - engines: {node: '>=18.18.0'} - - '@eslint-react/eff@2.13.0': - resolution: {integrity: sha512-rEH2R8FQnUAblUW+v3ZHDU1wEhatbL1+U2B1WVuBXwSKqzF7BGaLqCPIU7o9vofumz5MerVfaCtJgI8jYe2Btg==} - engines: {node: '>=20.19.0'} - - '@eslint-react/kit@1.53.1': - resolution: {integrity: sha512-zOi2le9V4rMrJvQV4OeedGvMGvDT46OyFPOwXKs7m0tQu5vXVJ8qwIPaVQT1n/WIuvOg49OfmAVaHpGxK++xLQ==} - engines: {node: '>=18.18.0'} + eslint: '*' + typescript: '*' - '@eslint-react/shared@1.53.1': - resolution: {integrity: sha512-gomJQmFqQgQVI3Ra4vTMG/s6a4bx3JqeNiTBjxBJt4C9iGaBj458GkP4LJHX7TM6xUzX+fMSKOPX7eV3C/+UCw==} - engines: {node: '>=18.18.0'} + '@eslint-react/eslint@5.9.0': + resolution: {integrity: sha512-PEJPNXLjzlpdq2A4+9XlVdYziZPGq7wM+PB8jtmUzurQuZ8dqfCoBiQNuu+8TYMPGet1lUjHhijCO8MM9mEfrg==} + engines: {node: '>=22.0.0'} + peerDependencies: + eslint: '*' + typescript: '*' - '@eslint-react/shared@2.13.0': - resolution: {integrity: sha512-IOloCqrZ7gGBT4lFf9+0/wn7TfzU7JBRjYwTSyb9SDngsbeRrtW95ZpgUpS8/jen1wUEm6F08duAooTZ2FtsWA==} - engines: {node: '>=20.19.0'} + '@eslint-react/jsx@5.9.0': + resolution: {integrity: sha512-dc6hBagLgCt+CSkWSJjbyPDGGcs/J9qHTdymMQrw51bO+DIztQpuy42E42EjOdxWcaw3U0eUtu330nZEcKqGMw==} + engines: {node: '>=22.0.0'} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + eslint: '*' + typescript: '*' - '@eslint-react/var@1.53.1': - resolution: {integrity: sha512-yzwopvPntcHU7mmDvWzRo1fb8QhjD8eDRRohD11rTV1u7nWO4QbJi0pOyugQakvte1/W11Y0Vr8Of0Ojk/A6zg==} - engines: {node: '>=18.18.0'} + '@eslint-react/shared@5.9.0': + resolution: {integrity: sha512-Ln255YTTUSlONr+e0Lu1wi2X9fTuOlNNJNXTz6PYaNZFAwCNWdlhkzFL8HdIBgPiWPUKrt+OMuah8o0xVoHswA==} + engines: {node: '>=22.0.0'} + peerDependencies: + eslint: '*' + typescript: '*' - '@eslint-react/var@2.13.0': - resolution: {integrity: sha512-dM+QaeiHR16qPQoJYg205MkdHYSWVa2B7ore5OFpOPlSwqDV3tLW7I+475WjbK7potq5QNPTxRa7VLp9FGeQqA==} - engines: {node: '>=20.19.0'} + '@eslint-react/var@5.9.0': + resolution: {integrity: sha512-vNz4y4eFKRYetihXiiZueGgClsyTFhR3kltMDPwoZyJaERdkyeoUylY09OnWakJFitao1+s2eBkSVuFqA8dqrA==} + engines: {node: '>=22.0.0'} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + eslint: '*' + typescript: '*' '@eslint/config-array@0.21.2': resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} @@ -1117,9 +1103,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - birecord@0.1.1: - resolution: {integrity: sha512-VUpsf/qykW0heRlC8LooCq28Kxn3mAqKohhDG/49rrsQ1dT1CXyj/pgXS+5BSRzFTR/3DyIBOqQOrGyZOh71Aw==} - brace-expansion@1.1.13: resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} @@ -1289,12 +1272,12 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-plugin-react-dom@2.13.0: - resolution: {integrity: sha512-+2IZzQ1WEFYOWatW+xvNUqmZn55YBCufzKA7hX3XQ/8eu85Mp4vnlOyNvdVHEOGhUnGuC6+9+zLK+IlEHKdKLQ==} - engines: {node: '>=20.19.0'} + eslint-plugin-react-dom@5.9.0: + resolution: {integrity: sha512-gBlV304swaW2S0MqVFkQhii0C+KAy2WmxFtVtho39h5GzWdjKjNIxdUdOPQvLAFd7B1/lkbJflqGQKf6sjWGTg==} + engines: {node: '>=22.0.0'} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' + eslint: '*' + typescript: '*' eslint-plugin-react-hooks@5.2.0: resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} @@ -1307,18 +1290,12 @@ packages: peerDependencies: eslint: '>=8.40' - eslint-plugin-react-x@1.53.1: - resolution: {integrity: sha512-MwMNnVwiPem0U6SlejDF/ddA4h/lmP6imL1RDZ2m3pUBrcdcOwOx0gyiRVTA3ENnhRlWfHljHf5y7m8qDSxMEg==} - engines: {node: '>=18.18.0'} + eslint-plugin-react-x@5.9.0: + resolution: {integrity: sha512-urgjMTtZpUzhkFBbQqp4+vdFhQmSkgeLnpq1h/2gemnzKjiMpDa9cCbo1vhjHnYQLzU6YRbxJ1hhqVv+9nXbjw==} + engines: {node: '>=22.0.0'} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - ts-api-utils: ^2.1.0 - typescript: ^4.9.5 || ^5.3.3 - peerDependenciesMeta: - ts-api-utils: - optional: true - typescript: - optional: true + eslint: '*' + typescript: '*' eslint-scope@8.4.0: resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} @@ -1509,12 +1486,6 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - is-immutable-type@5.0.4: - resolution: {integrity: sha512-tDf0vB9dJJt/1USS2nvHJb8UsIAhs+pF6z8UZLNdhrzB+PKMrdcN45je9jhuFpaJOjJpoRhueFmFrRs5g/TNMA==} - peerDependencies: - eslint: '*' - typescript: '>=4.7.4' - isbot@5.1.42: resolution: {integrity: sha512-/SXsVh7KpPRISrD4ffrGSxnTLlUBzEQUfWIusaJPrpJ93FW1P0YEZri5vAUkFsA0m2HRUhQRQadk2wJ+EeKowQ==} engines: {node: '>=18'} @@ -1844,8 +1815,8 @@ packages: tabbable@6.4.0: resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} - tar@7.5.16: - resolution: {integrity: sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==} + tar@7.5.19: + resolution: {integrity: sha512-4LeEWl96twnS2Q7Bz4MGqgazLqO+hJN63GZxXoIqh1T3VweYD997gbU1ItNsQafqqXTXd5WFyFdReLtwvRBNiw==} engines: {node: '>=18'} tinyexec@0.3.2: @@ -1861,11 +1832,6 @@ packages: peerDependencies: typescript: '>=4.8.4' - ts-declaration-location@1.0.7: - resolution: {integrity: sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==} - peerDependencies: - typescript: '>=4.0.0' - ts-pattern@5.9.0: resolution: {integrity: sha512-6s5V71mX8qBUmlgbrfL33xDUwO0fq48rxAu2LBE11WBeGdpCPOsXksQbZJHvHwhrd3QjUusd3mAOM5Gg0mFBLg==} @@ -1894,8 +1860,8 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} engines: {node: '>=14.17'} hasBin: true @@ -2264,127 +2230,76 @@ snapshots: '@eslint-community/regexpp@4.12.2': {} - '@eslint-react/ast@1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': - dependencies: - '@eslint-react/eff': 1.53.1 - '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/typescript-estree': 8.61.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - string-ts: 2.3.1 - ts-pattern: 5.9.0 - transitivePeerDependencies: - - eslint - - supports-color - - typescript - - '@eslint-react/ast@2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': + '@eslint-react/ast@5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-react/eff': 2.13.0 '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/typescript-estree': 8.61.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) eslint: 9.39.4(jiti@2.7.0) string-ts: 2.3.1 - typescript: 5.8.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@eslint-react/core@1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': - dependencies: - '@eslint-react/ast': 1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/eff': 1.53.1 - '@eslint-react/kit': 1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/shared': 1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/var': 1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.61.0 - '@typescript-eslint/type-utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - birecord: 0.1.1 - ts-pattern: 5.9.0 - transitivePeerDependencies: - - eslint - - supports-color - - typescript - - '@eslint-react/core@2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': + '@eslint-react/core@5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-react/ast': 2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/eff': 2.13.0 - '@eslint-react/shared': 2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/var': 2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@eslint-react/ast': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/eslint': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/jsx': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/shared': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/var': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) '@typescript-eslint/scope-manager': 8.61.0 '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) eslint: 9.39.4(jiti@2.7.0) ts-pattern: 5.9.0 - typescript: 5.8.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@eslint-react/eff@1.53.1': {} - - '@eslint-react/eff@2.13.0': {} - - '@eslint-react/kit@1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': + '@eslint-react/eslint@5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-react/eff': 1.53.1 - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - ts-pattern: 5.9.0 - zod: 4.4.3 + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + eslint: 9.39.4(jiti@2.7.0) + typescript: 6.0.3 transitivePeerDependencies: - - eslint - supports-color - - typescript - '@eslint-react/shared@1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': + '@eslint-react/jsx@5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-react/eff': 1.53.1 - '@eslint-react/kit': 1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@eslint-react/ast': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/eslint': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/shared': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/var': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + eslint: 9.39.4(jiti@2.7.0) ts-pattern: 5.9.0 - zod: 4.4.3 + typescript: 6.0.3 transitivePeerDependencies: - - eslint - supports-color - - typescript - '@eslint-react/shared@2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': + '@eslint-react/shared@5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-react/eff': 2.13.0 - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@eslint-react/eslint': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) eslint: 9.39.4(jiti@2.7.0) ts-pattern: 5.9.0 - typescript: 5.8.3 + typescript: 6.0.3 zod: 4.4.3 transitivePeerDependencies: - supports-color - '@eslint-react/var@1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': + '@eslint-react/var@5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-react/ast': 1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/eff': 1.53.1 + '@eslint-react/ast': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/eslint': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) '@typescript-eslint/scope-manager': 8.61.0 '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - string-ts: 2.3.1 - ts-pattern: 5.9.0 - transitivePeerDependencies: - - eslint - - supports-color - - typescript - - '@eslint-react/var@2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': - dependencies: - '@eslint-react/ast': 2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/eff': 2.13.0 - '@eslint-react/shared': 2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.61.0 - '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) eslint: 9.39.4(jiti@2.7.0) ts-pattern: 5.9.0 - typescript: 5.8.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -2452,9 +2367,9 @@ snapshots: '@floating-ui/utils@0.2.11': {} - '@hey-api/client-axios@0.7.1(@hey-api/openapi-ts@0.66.7(typescript@5.8.3))(axios@1.17.0)': + '@hey-api/client-axios@0.7.1(@hey-api/openapi-ts@0.66.7(typescript@6.0.3))(axios@1.17.0)': dependencies: - '@hey-api/openapi-ts': 0.66.7(typescript@5.8.3) + '@hey-api/openapi-ts': 0.66.7(typescript@6.0.3) axios: 1.17.0 '@hey-api/json-schema-ref-parser@1.0.5': @@ -2464,13 +2379,13 @@ snapshots: js-yaml: 4.2.0 lodash: 4.18.1 - '@hey-api/openapi-ts@0.66.7(typescript@5.8.3)': + '@hey-api/openapi-ts@0.66.7(typescript@6.0.3)': dependencies: '@hey-api/json-schema-ref-parser': 1.0.5 c12: 2.0.1 commander: 13.0.0 handlebars: 4.7.9 - typescript: 5.8.3 + typescript: 6.0.3 transitivePeerDependencies: - magicast @@ -2646,18 +2561,18 @@ snapshots: '@tanstack/devtools-event-client@0.4.3': {} - '@tanstack/eslint-plugin-query@5.101.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': + '@tanstack/eslint-plugin-query@5.101.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) eslint: 9.39.4(jiti@2.7.0) optionalDependencies: - typescript: 5.8.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@tanstack/eslint-plugin-router@1.162.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': + '@tanstack/eslint-plugin-router@1.162.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) eslint: 9.39.4(jiti@2.7.0) transitivePeerDependencies: - supports-color @@ -2851,40 +2766,40 @@ snapshots: dependencies: csstype: 3.2.3 - '@typescript-eslint/eslint-plugin@8.61.0(@typescript-eslint/parser@8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.61.0(@typescript-eslint/parser@8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@typescript-eslint/parser': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) '@typescript-eslint/scope-manager': 8.61.0 - '@typescript-eslint/type-utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@typescript-eslint/type-utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.61.0 eslint: 9.39.4(jiti@2.7.0) ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.5.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': + '@typescript-eslint/parser@8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': dependencies: '@typescript-eslint/scope-manager': 8.61.0 '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/typescript-estree': 8.61.0(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.61.0 debug: 4.4.3 eslint: 9.39.4(jiti@2.7.0) - typescript: 5.8.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.61.0(typescript@5.8.3)': + '@typescript-eslint/project-service@8.61.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) '@typescript-eslint/types': 8.61.0 debug: 4.4.3 - typescript: 5.8.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -2893,47 +2808,47 @@ snapshots: '@typescript-eslint/types': 8.61.0 '@typescript-eslint/visitor-keys': 8.61.0 - '@typescript-eslint/tsconfig-utils@8.61.0(typescript@5.8.3)': + '@typescript-eslint/tsconfig-utils@8.61.0(typescript@6.0.3)': dependencies: - typescript: 5.8.3 + typescript: 6.0.3 - '@typescript-eslint/type-utils@8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': dependencies: '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/typescript-estree': 8.61.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) debug: 4.4.3 eslint: 9.39.4(jiti@2.7.0) - ts-api-utils: 2.5.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color '@typescript-eslint/types@8.61.0': {} - '@typescript-eslint/typescript-estree@8.61.0(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.61.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.61.0(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@5.8.3) + '@typescript-eslint/project-service': 8.61.0(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) '@typescript-eslint/types': 8.61.0 '@typescript-eslint/visitor-keys': 8.61.0 debug: 4.4.3 minimatch: 10.2.5 semver: 7.8.4 tinyglobby: 0.2.17 - ts-api-utils: 2.5.0(typescript@5.8.3) - typescript: 5.8.3 + ts-api-utils: 2.5.0(typescript@6.0.3) + typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3)': + '@typescript-eslint/utils@8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4(jiti@2.7.0)) '@typescript-eslint/scope-manager': 8.61.0 '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/typescript-estree': 8.61.0(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) eslint: 9.39.4(jiti@2.7.0) - typescript: 5.8.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -3012,8 +2927,6 @@ snapshots: baseline-browser-mapping@2.10.35: {} - birecord@0.1.1: {} - brace-expansion@1.1.13: dependencies: balanced-match: 1.0.2 @@ -3191,20 +3104,17 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-plugin-react-dom@2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3): + eslint-plugin-react-dom@5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3): dependencies: - '@eslint-react/ast': 2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/core': 2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/eff': 2.13.0 - '@eslint-react/shared': 2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/var': 2.13.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@typescript-eslint/scope-manager': 8.61.0 + '@eslint-react/ast': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/eslint': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/jsx': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/shared': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) compare-versions: 6.1.1 eslint: 9.39.4(jiti@2.7.0) - ts-pattern: 5.9.0 - typescript: 5.8.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -3216,26 +3126,25 @@ snapshots: dependencies: eslint: 9.39.4(jiti@2.7.0) - eslint-plugin-react-x@1.53.1(eslint@9.39.4(jiti@2.7.0))(ts-api-utils@2.5.0(typescript@5.8.3))(typescript@5.8.3): + eslint-plugin-react-x@5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3): dependencies: - '@eslint-react/ast': 1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/core': 1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/eff': 1.53.1 - '@eslint-react/kit': 1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/shared': 1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@eslint-react/var': 1.53.1(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@eslint-react/ast': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/core': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/eslint': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/jsx': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/shared': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@eslint-react/var': 5.9.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) '@typescript-eslint/scope-manager': 8.61.0 - '@typescript-eslint/type-utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@typescript-eslint/type-utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) compare-versions: 6.1.1 eslint: 9.39.4(jiti@2.7.0) - is-immutable-type: 5.0.4(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) string-ts: 2.3.1 + ts-api-utils: 2.5.0(typescript@6.0.3) ts-pattern: 5.9.0 - optionalDependencies: - ts-api-utils: 2.5.0(typescript@5.8.3) - typescript: 5.8.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -3378,7 +3287,7 @@ snapshots: node-fetch-native: 1.6.7 nypm: 0.5.4 pathe: 2.0.3 - tar: 7.5.16 + tar: 7.5.19 glob-parent@6.0.2: dependencies: @@ -3441,16 +3350,6 @@ snapshots: dependencies: is-extglob: 2.1.1 - is-immutable-type@5.0.4(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3): - dependencies: - '@typescript-eslint/type-utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - eslint: 9.39.4(jiti@2.7.0) - ts-api-utils: 2.5.0(typescript@5.8.3) - ts-declaration-location: 1.0.7(typescript@5.8.3) - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - isbot@5.1.42: {} isexe@2.0.0: {} @@ -3751,7 +3650,7 @@ snapshots: tabbable@6.4.0: {} - tar@7.5.16: + tar@7.5.19: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 @@ -3766,20 +3665,15 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - ts-api-utils@2.5.0(typescript@5.8.3): + ts-api-utils@2.5.0(typescript@6.0.3): dependencies: - typescript: 5.8.3 - - ts-declaration-location@1.0.7(typescript@5.8.3): - dependencies: - picomatch: 4.0.4 - typescript: 5.8.3 + typescript: 6.0.3 ts-pattern@5.9.0: {} - tsconfck@3.1.6(typescript@5.8.3): + tsconfck@3.1.6(typescript@6.0.3): optionalDependencies: - typescript: 5.8.3 + typescript: 6.0.3 tslib@2.8.1: {} @@ -3787,18 +3681,18 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typescript-eslint@8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3): + typescript-eslint@8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.61.0(@typescript-eslint/parser@8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3))(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@typescript-eslint/parser': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) - '@typescript-eslint/typescript-estree': 8.61.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@5.8.3) + '@typescript-eslint/eslint-plugin': 8.61.0(@typescript-eslint/parser@8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3))(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@9.39.4(jiti@2.7.0))(typescript@6.0.3) eslint: 9.39.4(jiti@2.7.0) - typescript: 5.8.3 + typescript: 6.0.3 transitivePeerDependencies: - supports-color - typescript@5.8.3: {} + typescript@6.0.3: {} ufo@1.6.4: {} @@ -3825,11 +3719,11 @@ snapshots: dependencies: react: 19.2.7 - vite-tsconfig-paths@6.1.1(typescript@5.8.3)(vite@6.4.3(jiti@2.7.0)): + vite-tsconfig-paths@6.1.1(typescript@6.0.3)(vite@6.4.3(jiti@2.7.0)): dependencies: debug: 4.4.3 globrex: 0.1.2 - tsconfck: 3.1.6(typescript@5.8.3) + tsconfck: 3.1.6(typescript@6.0.3) vite: 6.4.3(jiti@2.7.0) transitivePeerDependencies: - supports-color diff --git a/frontend/src/components/Header.tsx b/frontend/src/components/Header.tsx index 23f82945..3d914b68 100644 --- a/frontend/src/components/Header.tsx +++ b/frontend/src/components/Header.tsx @@ -70,11 +70,17 @@ function LockStatusIcon({ ); } -function ProjectInfoItem({ label, value }: { label: string; value?: string }) { +function ProjectInfoItem({ + label, + value, +}: { + label: string; + value?: string | undefined; +}) { return ( {label} - + {value ?? "not set"} diff --git a/frontend/src/components/LockExpireNotification.tsx b/frontend/src/components/LockExpireNotification.tsx index 41b49225..bb6d675d 100644 --- a/frontend/src/components/LockExpireNotification.tsx +++ b/frontend/src/components/LockExpireNotification.tsx @@ -57,10 +57,18 @@ export function LockExpireNotification() { }); useEffect(() => { + let ignore = false; + if (!isLockAcquired || !lockInfo) { - setTimeUntilExpire(Number.POSITIVE_INFINITY); + void Promise.resolve().then(() => { + if (!ignore) { + setTimeUntilExpire(Number.POSITIVE_INFINITY); + } + }); - return; + return () => { + ignore = true; + }; } const initialTimeLeft = Math.max( @@ -68,7 +76,11 @@ export function LockExpireNotification() { Math.ceil(lockInfo.expires_at - Date.now() / 1000), ); - setTimeUntilExpire(initialTimeLeft); + void Promise.resolve().then(() => { + if (!ignore) { + setTimeUntilExpire(initialTimeLeft); + } + }); const interval = setInterval(() => { setTimeUntilExpire((currentTimeLeft) => { @@ -81,6 +93,7 @@ export function LockExpireNotification() { }, 1000); return () => { + ignore = true; clearInterval(interval); }; }, [isLockAcquired, lockInfo]); @@ -95,7 +108,9 @@ export function LockExpireNotification() { isDialogOpen && timeUntilExpire > projectLockExpireNotificationThreshold ) { - setIsDialogOpen(false); + void Promise.resolve().then(() => { + setIsDialogOpen(false); + }); } else if ( isLockAcquired && !isDialogOpen && @@ -133,7 +148,9 @@ export function LockExpireNotification() { !isLockAcquired && timeUntilExpire !== Number.POSITIVE_INFINITY ) { - setTimeUntilExpire(Number.POSITIVE_INFINITY); + void Promise.resolve().then(() => { + setTimeUntilExpire(Number.POSITIVE_INFINITY); + }); } }, [isDialogOpen, isLockAcquired, timeUntilExpire, queryClient]); diff --git a/frontend/src/components/LockStatus.tsx b/frontend/src/components/LockStatus.tsx index 9652e7fa..fc622eff 100644 --- a/frontend/src/components/LockStatus.tsx +++ b/frontend/src/components/LockStatus.tsx @@ -14,7 +14,11 @@ import type { LockInfo, LockStatus } from "#client/types.gen"; import { Banner } from "#styles/common"; import { displayTimestamp } from "#utils/datetime"; -function EnableEditingButton({ lockStatus }: { lockStatus?: LockStatus }) { +function EnableEditingButton({ + lockStatus, +}: { + lockStatus?: LockStatus | undefined; +}) { const queryClient = useQueryClient(); const { mutate } = useMutation({ ...projectPostLockAcquireMutation(), @@ -130,7 +134,11 @@ export function LockIcon({ isReadOnly }: { isReadOnly: boolean }) { ); } -export function LockStatusBanner({ lockStatus }: { lockStatus?: LockStatus }) { +export function LockStatusBanner({ + lockStatus, +}: { + lockStatus?: LockStatus | undefined; +}) { const isReadOnly = !(lockStatus?.is_lock_acquired ?? false); return ( diff --git a/frontend/src/components/ProjectRecoveryNotification.tsx b/frontend/src/components/ProjectRecoveryNotification.tsx index 75d5072c..49a2c4bb 100644 --- a/frontend/src/components/ProjectRecoveryNotification.tsx +++ b/frontend/src/components/ProjectRecoveryNotification.tsx @@ -61,29 +61,24 @@ export function ProjectRecoveryNotification() { // biome-ignore lint/correctness/useExhaustiveDependencies: selectProjectInvalidAttempt intentionally retriggers this effect useEffect(() => { - async function checkSnapshots() { - try { - const { data } = await projectGetCache({ - query: { resource: CACHE_RESOURCE_PROJECT_CONFIG }, - throwOnError: true, - }); - setLatestRevision( - data.revisions.length > 0 - ? data.revisions[data.revisions.length - 1] - : null, - ); - setIsOpen(true); - } catch { - setLatestRevision(null); - setIsOpen(true); - } - } - if (project.errorStatus === HTTP_STATUS_422_UNPROCESSABLE_CONTENT) { - void checkSnapshots(); + void projectGetCache({ + query: { resource: CACHE_RESOURCE_PROJECT_CONFIG }, + throwOnError: true, + }) + .then(({ data }) => { + setLatestRevision(data.revisions.at(-1) ?? null); + setIsOpen(true); + }) + .catch(() => { + setLatestRevision(null); + setIsOpen(true); + }); } else { - setLatestRevision(null); - setIsOpen(false); + void Promise.resolve().then(() => { + setLatestRevision(null); + setIsOpen(false); + }); } }, [project.errorStatus, selectProjectInvalidAttempt]); diff --git a/frontend/src/components/common.tsx b/frontend/src/components/common.tsx index a8937ab2..cecdaecf 100644 --- a/frontend/src/components/common.tsx +++ b/frontend/src/components/common.tsx @@ -26,13 +26,13 @@ import { import { handleSsoLogin } from "#utils/authentication"; type StatusCodeHandlingProps = { - message?: string; - enableRetry?: boolean; + message?: string | undefined; + enableRetry?: boolean | undefined; }; type ErrorFallbackProps = { - header?: string; - statusCodeHandling?: Record; + header?: string | undefined; + statusCodeHandling?: Record | undefined; }; export function Loading() { @@ -55,10 +55,10 @@ function ErrorFallback({ error.response.status in statusCodeHandling ) { const handling = statusCodeHandling[error.response.status]; - if (handling.message !== undefined) { + if (handling?.message !== undefined) { message = handling.message; } - if (handling.enableRetry !== undefined) { + if (handling?.enableRetry !== undefined) { enableRetry = handling.enableRetry; } } diff --git a/frontend/src/components/form/button.tsx b/frontend/src/components/form/button.tsx index b65e5445..cab7519b 100644 --- a/frontend/src/components/form/button.tsx +++ b/frontend/src/components/form/button.tsx @@ -7,12 +7,15 @@ import { type GeneralButtonProps = { label: string; - isPending?: boolean; - disabled?: boolean; - tooltipText?: string; - onClick?: (e: React.MouseEvent) => void; - onMouseDown?: (e: React.MouseEvent) => void; -} & Pick; + isPending?: boolean | undefined; + disabled?: boolean | undefined; + tooltipText?: string | undefined; + onClick?: ((e: React.MouseEvent) => void) | undefined; + onMouseDown?: ((e: React.MouseEvent) => void) | undefined; + variant?: ButtonProps["variant"] | undefined; + color?: ButtonProps["color"] | undefined; + type?: ButtonProps["type"] | undefined; +}; export function GeneralButton({ type = "button", @@ -29,9 +32,9 @@ export function GeneralButton({ + diff --git a/frontend/src/components/project/rms/Overview.tsx b/frontend/src/components/project/rms/Overview.tsx index 863bb5dc..651fabae 100644 --- a/frontend/src/components/project/rms/Overview.tsx +++ b/frontend/src/components/project/rms/Overview.tsx @@ -192,7 +192,7 @@ function RmsEditorForm({ {([isDefaultValue, canSubmit]) => ( @@ -342,9 +342,9 @@ function RmsProjectActions({ disabled={projectCloseMutation.isPending} variant={isRmsProjectOpen ? "outlined" : "contained"} onClick={() => { - projectOpenMutation.mutate({ - body: useRmsVersion ? { version: useRmsVersion } : undefined, - }); + projectOpenMutation.mutate( + useRmsVersion ? { body: { version: useRmsVersion } } : {}, + ); }} /> diff --git a/frontend/src/components/project/rms/Stratigraphy.tsx b/frontend/src/components/project/rms/Stratigraphy.tsx index 3b885868..0867de83 100644 --- a/frontend/src/components/project/rms/Stratigraphy.tsx +++ b/frontend/src/components/project/rms/Stratigraphy.tsx @@ -424,7 +424,9 @@ function Edit({ {([isDefaultValue, canSubmit]) => ( ` max-height: ${({ $maxHeight }) => $maxHeight}; diff --git a/frontend/src/components/project/stratigraphicFramework/StratigraphicFramework.tsx b/frontend/src/components/project/stratigraphicFramework/StratigraphicFramework.tsx index c4f21126..ebe713be 100644 --- a/frontend/src/components/project/stratigraphicFramework/StratigraphicFramework.tsx +++ b/frontend/src/components/project/stratigraphicFramework/StratigraphicFramework.tsx @@ -57,7 +57,8 @@ export function StratigraphicFramework({ ].join("-"); const [notWidthConstrained, setNotWidthConstrained] = useState( - enableWidthExpansion && + () => + enableWidthExpansion && getStorageItem(sessionStorage, storageKeyWidthConstraint, "boolean"), ); diff --git a/frontend/src/components/project/stratigraphicFramework/types.ts b/frontend/src/components/project/stratigraphicFramework/types.ts index 7eb762a8..e30f7c71 100644 --- a/frontend/src/components/project/stratigraphicFramework/types.ts +++ b/frontend/src/components/project/stratigraphicFramework/types.ts @@ -17,8 +17,12 @@ export type FrameworkData = { unselectedHorizonNamesSet: Set; unselectedZoneNamesSet: Set; horizonsUsedByZones: Set; - onHorizonClick?: (horizon: RmsHorizon, isUnselected: boolean) => void; - onZoneClick?: (zone: RmsStratigraphicZone, isUnselected: boolean) => void; + onHorizonClick?: + | ((horizon: RmsHorizon, isUnselected: boolean) => void) + | undefined; + onZoneClick?: + | ((zone: RmsStratigraphicZone, isUnselected: boolean) => void) + | undefined; zoneGridPlacement: Map; numStratColumns: number; }; diff --git a/frontend/src/components/project/stratigraphy/Overview.style.ts b/frontend/src/components/project/stratigraphy/Overview.style.ts index 03864c37..8791fe8d 100644 --- a/frontend/src/components/project/stratigraphy/Overview.style.ts +++ b/frontend/src/components/project/stratigraphy/Overview.style.ts @@ -109,7 +109,7 @@ export const ElementInfo = styled.div.attrs<{ `; export const ElementSystemName = styled.div.attrs<{ - $elementType?: ElementType; + $elementType?: ElementType | undefined; $isMissingvalue?: boolean; }>((props) => ({ $elementType: props.$elementType, diff --git a/frontend/src/components/project/stratigraphy/Overview.tsx b/frontend/src/components/project/stratigraphy/Overview.tsx index f84c9912..d2b361ac 100644 --- a/frontend/src/components/project/stratigraphy/Overview.tsx +++ b/frontend/src/components/project/stratigraphy/Overview.tsx @@ -8,7 +8,14 @@ import { useSuspenseQuery, } from "@tanstack/react-query"; import { Link } from "@tanstack/react-router"; -import { useEffect, useMemo, useState } from "react"; +import { + type Dispatch, + type SetStateAction, + useCallback, + useEffect, + useMemo, + useState, +} from "react"; import { toast } from "react-toastify"; import type { RmsProject, StratigraphicColumn } from "#client"; @@ -251,9 +258,11 @@ function Edit({ { - if (!(horizon.name in mappingData.elementMappings)) { + const elementMapping = mappingData.elementMappings[horizon.name]; + if (elementMapping === undefined) { return null; } @@ -514,7 +524,7 @@ function Elements({ elementType }: { elementType: ElementType }) { $lineStyle={getHorizonLineStyle(horizon)} > @@ -522,15 +532,16 @@ function Elements({ elementType }: { elementType: ElementType }) { }) : frameworkData.zones.map((zone) => { const grid = frameworkData.zoneGridPlacement.get(zone.name); + const elementMapping = mappingData.elementMappings[zone.name]; - if (!(grid && zone.name in mappingData.elementMappings)) { + if (!grid || elementMapping === undefined) { return null; } return ( @@ -548,30 +559,53 @@ export function Overview({ editMode, }: { rmsProject: RmsProject; - stratigraphicColumn?: StratigraphicColumn; + stratigraphicColumn?: StratigraphicColumn | undefined; smdaHealthStatus: boolean; projectReadOnly: boolean; editMode: boolean; }) { - const [elementMappings, setElementMappings] = useState({}); - const { data: projectMappings } = useSuspenseQuery( projectGetMappingsOptions({ path: mappingsPaths.stratigraphyRms, }), ); - useEffect(() => { + const baseElementMappings = useMemo(() => { const lookup = createProjectMappingsLookup("stratigraphy", projectMappings); - const elementMappings: ElementMappings = { + return { ...createElementMappings("horizon", rmsProject.horizons ?? [], lookup), ...createElementMappings("zone", rmsProject.zones ?? [], lookup), }; - - setElementMappings(elementMappings); }, [projectMappings, rmsProject.horizons, rmsProject.zones]); + const [elementMappingsState, setElementMappingsState] = useState(() => ({ + base: baseElementMappings, + mappings: baseElementMappings, + })); + const elementMappings = + elementMappingsState.base === baseElementMappings + ? elementMappingsState.mappings + : baseElementMappings; + const setElementMappings: Dispatch> = + useCallback( + (value) => { + setElementMappingsState((current) => { + const currentMappings = + current.base === baseElementMappings + ? current.mappings + : baseElementMappings; + + return { + base: baseElementMappings, + mappings: + typeof value === "function" ? value(currentMappings) : value, + }; + }); + }, + [baseElementMappings], + ); + const mappingData = useMemo(() => { return { elementMappings, @@ -590,6 +624,7 @@ export function Overview({ editMode, smdaHealthStatus, stratigraphicColumn, + setElementMappings, ]); return ( diff --git a/frontend/src/components/project/stratigraphy/functions.ts b/frontend/src/components/project/stratigraphy/functions.ts index b7353249..06bd6c05 100644 --- a/frontend/src/components/project/stratigraphy/functions.ts +++ b/frontend/src/components/project/stratigraphy/functions.ts @@ -35,10 +35,16 @@ export function createStratUnitOptions(stratUnits: StratigraphicUnit[]) { const relations: StratUnitRelation[] = []; for (const stratUnit of stratUnits) { const unit = lookup[stratUnit.identifier]; + if (unit === undefined) { + continue; + } if (stratUnit.strat_unit_parent === null) { relations.push(unit); } else { const parent = lookup[stratUnit.strat_unit_parent]; + if (parent === undefined) { + continue; + } parent.children.push(unit); } } @@ -61,6 +67,9 @@ export function createHorizonOptions( ) .forEach((zone) => { const zoneMapping = elementMappings[zone.name]; + if (zoneMapping === undefined) { + return; + } if (zoneMapping.unmappable || zoneMapping.smdaUuid === "") { return; } diff --git a/frontend/src/components/project/stratigraphy/types.ts b/frontend/src/components/project/stratigraphy/types.ts index 6f274d22..839efdf2 100644 --- a/frontend/src/components/project/stratigraphy/types.ts +++ b/frontend/src/components/project/stratigraphy/types.ts @@ -3,7 +3,7 @@ import type { StratigraphicUnit } from "#client"; export type ElementType = "horizon" | "zone"; export type ElementMapping = { - elementType?: ElementType; + elementType?: ElementType | undefined; rmsName: string; unmappable: boolean; smdaName: string; diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 8e843b66..98c2bada 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -223,8 +223,9 @@ export function App() { acquireAndPatchSsoAccessTokenPromise.current ??= (async () => { const account = msalInstance.getActiveAccount(); const accounts = msalInstance.getAllAccounts(); + const tokenAccount = account ?? accounts.at(0); - if (!account && accounts.length === 0) { + if (tokenAccount === undefined) { await msalInstance.acquireTokenRedirect({ scopes: ssoScopes }); return; @@ -233,7 +234,7 @@ export function App() { const result = await msalInstance .acquireTokenSilent({ scopes: ssoScopes, - account: account ?? accounts[0], + account: tokenAccount, }) .catch((error: unknown) => { if (error instanceof InteractionRequiredAuthError) { @@ -273,21 +274,27 @@ export function App() { acquireAndPatchSsoAccessToken, ), ); - setHasResponseInterceptor(true); + void Promise.resolve().then(() => { + setHasResponseInterceptor(true); + }); } return () => { if (id !== undefined) { client.instance.interceptors.response.eject(id); - setHasResponseInterceptor(false); + void Promise.resolve().then(() => { + setHasResponseInterceptor(false); + }); } }; }, [acquireAndPatchSsoAccessToken, apiToken, apiTokenStatus.valid]); useEffect(() => { if (!isApiTokenNonEmpty(apiToken)) { - setSessionReady(false); - setSessionCreationFailed(false); + void Promise.resolve().then(() => { + setSessionReady(false); + setSessionCreationFailed(false); + }); return; } @@ -299,7 +306,9 @@ export function App() { !isCreatingSession && !requestSessionCreation ) { - setRequestSessionCreation(true); + void Promise.resolve().then(() => { + setRequestSessionCreation(true); + }); } }, [ apiToken, @@ -316,8 +325,10 @@ export function App() { } if (requestSessionCreation && !isCreatingSession) { - setIsCreatingSession(true); - setSessionCreationFailed(false); + void Promise.resolve().then(() => { + setIsCreatingSession(true); + setSessionCreationFailed(false); + }); void callCreateSessionAsync() .then(() => { setSessionReady(true); @@ -338,7 +349,9 @@ export function App() { .finally(() => { setIsCreatingSession(false); }); - setRequestSessionCreation(false); + void Promise.resolve().then(() => { + setRequestSessionCreation(false); + }); } }, [ accessToken, @@ -352,7 +365,9 @@ export function App() { useEffect(() => { if (requestAcquireSsoAccessToken) { void acquireAndPatchSsoAccessToken(); - setRequestAcquireSsoAccessToken(false); + void Promise.resolve().then(() => { + setRequestAcquireSsoAccessToken(false); + }); } }, [acquireAndPatchSsoAccessToken, requestAcquireSsoAccessToken]); diff --git a/frontend/src/routes/project/index.tsx b/frontend/src/routes/project/index.tsx index 61b4f114..62c4911d 100644 --- a/frontend/src/routes/project/index.tsx +++ b/frontend/src/routes/project/index.tsx @@ -57,7 +57,7 @@ function ProjectInfo({ lockStatus, }: { projectData: FmuProject; - lockStatus?: LockStatus; + lockStatus?: LockStatus | undefined; }) { return ( <> diff --git a/frontend/src/routes/project/mappings/stratigraphy.tsx b/frontend/src/routes/project/mappings/stratigraphy.tsx index 55ffb97a..b3b098fa 100644 --- a/frontend/src/routes/project/mappings/stratigraphy.tsx +++ b/frontend/src/routes/project/mappings/stratigraphy.tsx @@ -23,7 +23,7 @@ export const Route = createFileRoute("/project/mappings/stratigraphy")({ }); function Content() { - const [editMode, setEditMode] = useState( + const [editMode, setEditMode] = useState(() => getStorageItem( sessionStorage, STORAGENAME_STRATIGRAPHY_EDIT_MODE, diff --git a/frontend/src/routes/project/masterdata.tsx b/frontend/src/routes/project/masterdata.tsx index a7d72e6b..850db1af 100644 --- a/frontend/src/routes/project/masterdata.tsx +++ b/frontend/src/routes/project/masterdata.tsx @@ -20,7 +20,7 @@ export const Route = createFileRoute("/project/masterdata")({ function Content() { const project = useProject(); const { data: healthCheck } = useSmdaHealthCheck(); - const [editMode, setEditMode] = useState( + const [editMode, setEditMode] = useState(() => getStorageItem(sessionStorage, STORAGENAME_MASTERDATA_EDIT_MODE, "boolean"), ); const { setRequestAcquireSsoAccessToken } = Route.useRouteContext(); diff --git a/frontend/src/routes/user/keys.tsx b/frontend/src/routes/user/keys.tsx index d2505f98..c7a13cb1 100644 --- a/frontend/src/routes/user/keys.tsx +++ b/frontend/src/routes/user/keys.tsx @@ -62,7 +62,7 @@ function KeysTextFieldForm({ formReset, }: MutationCallbackProps) => { mutate( - { body: { id: name, key: formValue[name] } }, + { body: { id: name, key: formValue[name] ?? "" } }, { onSuccess: (data) => { formSubmitCallback({ diff --git a/frontend/src/utils/model.ts b/frontend/src/utils/model.ts index be7e5b74..bdb58252 100644 --- a/frontend/src/utils/model.ts +++ b/frontend/src/utils/model.ts @@ -24,8 +24,9 @@ export function getNameFromNameUuidValue(value: NameUuidType) { export function getNameFromMultipleNameUuidValues(values: Array) { let name = ""; - if (values.length) { - name = getNameFromNameUuidValue(values[0]); + const firstValue = values.at(0); + if (firstValue !== undefined) { + name = getNameFromNameUuidValue(firstValue); if (values.length > 1) { name += ` (and ${String(values.length - 1)} more)`; } diff --git a/frontend/src/utils/string.ts b/frontend/src/utils/string.ts index f7591081..27c997df 100644 --- a/frontend/src/utils/string.ts +++ b/frontend/src/utils/string.ts @@ -7,8 +7,8 @@ export function isVersionLessThan(version: string, minimum: string) { const v2Parts = minimum.split(".").map(Number); for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) { - const v1 = v1Parts[i] || 0; - const v2 = v2Parts[i] || 0; + const v1 = v1Parts[i] ?? 0; + const v2 = v2Parts[i] ?? 0; if (v1 < v2) return true; if (v1 > v2) return false; } diff --git a/frontend/src/utils/ui.ts b/frontend/src/utils/ui.ts index aa1127dd..f136b6a5 100644 --- a/frontend/src/utils/ui.ts +++ b/frontend/src/utils/ui.ts @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useState } from "react"; export function useConfirmClose({ enable, @@ -10,12 +10,7 @@ export function useConfirmClose({ onCloseConfirmed: () => void; }) { const [confirmCloseDialogOpen, setConfirmCloseDialogOpen] = useState(false); - - useEffect(() => { - if (!enable) { - setConfirmCloseDialogOpen(false); - } - }, [enable]); + const isConfirmCloseDialogOpen = enable && confirmCloseDialogOpen; const closeDialogs = () => { setConfirmCloseDialogOpen(false); @@ -39,7 +34,7 @@ export function useConfirmClose({ }; return { - confirmCloseDialogOpen, + confirmCloseDialogOpen: isConfirmCloseDialogOpen, handleCloseRequest, handleDecision, }; diff --git a/frontend/src/utils/validator.ts b/frontend/src/utils/validator.ts index b0d892f7..a2962ec8 100644 --- a/frontend/src/utils/validator.ts +++ b/frontend/src/utils/validator.ts @@ -1,9 +1,9 @@ import z, { type ZodString } from "zod"; export interface ValidatorProps { - length?: number; - minLength?: number; - initialValue?: string; + length?: number | undefined; + minLength?: number | undefined; + initialValue?: string | undefined; } export function handleValidator({ diff --git a/frontend/tsconfig.app.json b/frontend/tsconfig.app.json index 735ed0bc..18a1a9da 100644 --- a/frontend/tsconfig.app.json +++ b/frontend/tsconfig.app.json @@ -1,16 +1,15 @@ { "compilerOptions": { "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", - "target": "es2024", + "target": "esnext", "useDefineForClassFields": true, - "lib": ["ES2024", "DOM", "DOM.Iterable"], - "module": "ESNext", + "module": "preserve", "skipLibCheck": true, + "verbatimModuleSyntax": true, /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, - "isolatedModules": true, "moduleDetection": "force", "noEmit": true, "jsx": "react-jsx", @@ -33,7 +32,8 @@ "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true + "noUncheckedIndexedAccess": true, + "exactOptionalPropertyTypes": true }, "include": ["src"] }