Compare commits
7 Commits
5c37234bf6
...
207476efdc
| Author | SHA1 | Date |
|---|---|---|
|
|
207476efdc | |
|
|
855c479caf | |
|
|
b46806ada1 | |
|
|
1e16d0e482 | |
|
|
9d3767d68c | |
|
|
4d2ba762f3 | |
|
|
6d32d2d005 |
|
|
@ -49,8 +49,10 @@ const RAW_RUNTIME_STATE =
|
|||
["prettier", "npm:3.8.1"],\
|
||||
["react", "npm:19.2.4"],\
|
||||
["react-bootstrap", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:2.10.10"],\
|
||||
["react-bootstrap-icons", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:1.11.6"],\
|
||||
["react-dom", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:19.2.4"],\
|
||||
["react-router-dom", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:7.13.1"],\
|
||||
["socket.io-client", "npm:4.8.3"],\
|
||||
["typescript", "patch:typescript@npm%3A5.9.3#optional!builtin<compat/typescript>::version=5.9.3&hash=5786d5"],\
|
||||
["typescript-eslint", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:8.56.1"],\
|
||||
["vite", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:7.3.1"],\
|
||||
|
|
@ -96,7 +98,7 @@ const RAW_RUNTIME_STATE =
|
|||
["@babel/types", "npm:7.29.0"],\
|
||||
["@jridgewell/remapping", "npm:2.3.5"],\
|
||||
["convert-source-map", "npm:2.0.0"],\
|
||||
["debug", "virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["gensync", "npm:1.0.0-beta.2"],\
|
||||
["json5", "npm:2.2.3"],\
|
||||
["semver", "npm:6.3.1"]\
|
||||
|
|
@ -312,7 +314,7 @@ const RAW_RUNTIME_STATE =
|
|||
["@babel/template", "npm:7.28.6"],\
|
||||
["@babel/traverse", "npm:7.29.0"],\
|
||||
["@babel/types", "npm:7.29.0"],\
|
||||
["debug", "virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3"]\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
|
|
@ -600,7 +602,7 @@ const RAW_RUNTIME_STATE =
|
|||
"packageDependencies": [\
|
||||
["@eslint/config-array", "npm:0.21.1"],\
|
||||
["@eslint/object-schema", "npm:2.1.7"],\
|
||||
["debug", "virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["minimatch", "npm:3.1.5"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
|
|
@ -632,7 +634,7 @@ const RAW_RUNTIME_STATE =
|
|||
"packageDependencies": [\
|
||||
["@eslint/eslintrc", "npm:3.3.4"],\
|
||||
["ajv", "npm:6.14.0"],\
|
||||
["debug", "virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["espree", "npm:10.4.0"],\
|
||||
["globals", "npm:14.0.0"],\
|
||||
["ignore", "npm:5.3.2"],\
|
||||
|
|
@ -1151,6 +1153,15 @@ const RAW_RUNTIME_STATE =
|
|||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@socket.io/component-emitter", [\
|
||||
["npm:3.1.2", {\
|
||||
"packageLocation": "./.yarn/cache/@socket.io-component-emitter-npm-3.1.2-bc4133d33f-c4242bad66.zip/node_modules/@socket.io/component-emitter/",\
|
||||
"packageDependencies": [\
|
||||
["@socket.io/component-emitter", "npm:3.1.2"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["@swc/helpers", [\
|
||||
["npm:0.5.19", {\
|
||||
"packageLocation": "./.yarn/cache/@swc-helpers-npm-0.5.19-8b3f562b85-30317ee644.zip/node_modules/@swc/helpers/",\
|
||||
|
|
@ -1377,7 +1388,7 @@ const RAW_RUNTIME_STATE =
|
|||
["@typescript-eslint/types", "npm:8.56.1"],\
|
||||
["@typescript-eslint/typescript-estree", "virtual:58ccd472628fcf79c5364cbafb0fa7401eab7f9f0a8d7e57daff8d16b3df3fcd9fae4f499821557ed433fdc33c9608f2e228cdb9e43ac4ccbde485d9fe0d92aa#npm:8.56.1"],\
|
||||
["@typescript-eslint/visitor-keys", "npm:8.56.1"],\
|
||||
["debug", "virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["eslint", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:9.39.3"],\
|
||||
["typescript", "patch:typescript@npm%3A5.9.3#optional!builtin<compat/typescript>::version=5.9.3&hash=5786d5"]\
|
||||
],\
|
||||
|
|
@ -1405,7 +1416,7 @@ const RAW_RUNTIME_STATE =
|
|||
["@typescript-eslint/project-service", "virtual:08eece7f558a61e3ba42d291e347c98bcfb1ebfb15f338a48676e1eb239671d197c1afd15b648b5d4feafc689a0004679f0f549b21e3ba4e2b84a1430d054544#npm:8.56.1"],\
|
||||
["@typescript-eslint/tsconfig-utils", "virtual:08eece7f558a61e3ba42d291e347c98bcfb1ebfb15f338a48676e1eb239671d197c1afd15b648b5d4feafc689a0004679f0f549b21e3ba4e2b84a1430d054544#npm:8.56.1"],\
|
||||
["@typescript-eslint/types", "npm:8.56.1"],\
|
||||
["debug", "virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["typescript", "patch:typescript@npm%3A5.9.3#optional!builtin<compat/typescript>::version=5.9.3&hash=5786d5"]\
|
||||
],\
|
||||
"packagePeers": [\
|
||||
|
|
@ -1465,7 +1476,7 @@ const RAW_RUNTIME_STATE =
|
|||
["@typescript-eslint/types", "npm:8.56.1"],\
|
||||
["@typescript-eslint/typescript-estree", "virtual:58ccd472628fcf79c5364cbafb0fa7401eab7f9f0a8d7e57daff8d16b3df3fcd9fae4f499821557ed433fdc33c9608f2e228cdb9e43ac4ccbde485d9fe0d92aa#npm:8.56.1"],\
|
||||
["@typescript-eslint/utils", "virtual:58ccd472628fcf79c5364cbafb0fa7401eab7f9f0a8d7e57daff8d16b3df3fcd9fae4f499821557ed433fdc33c9608f2e228cdb9e43ac4ccbde485d9fe0d92aa#npm:8.56.1"],\
|
||||
["debug", "virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["eslint", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:9.39.3"],\
|
||||
["ts-api-utils", "virtual:79e3fd711d219a7e195f7717b302bba495278e314f4cbf21fc912bccc21ee612c45d3bed436698ce744dcc117f9112db1d68749c33956122d7e1360e6bcb3f62#npm:2.4.0"],\
|
||||
["typescript", "patch:typescript@npm%3A5.9.3#optional!builtin<compat/typescript>::version=5.9.3&hash=5786d5"]\
|
||||
|
|
@ -1505,7 +1516,7 @@ const RAW_RUNTIME_STATE =
|
|||
["@typescript-eslint/types", "npm:8.56.1"],\
|
||||
["@typescript-eslint/typescript-estree", "virtual:58ccd472628fcf79c5364cbafb0fa7401eab7f9f0a8d7e57daff8d16b3df3fcd9fae4f499821557ed433fdc33c9608f2e228cdb9e43ac4ccbde485d9fe0d92aa#npm:8.56.1"],\
|
||||
["@typescript-eslint/visitor-keys", "npm:8.56.1"],\
|
||||
["debug", "virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["minimatch", "npm:10.2.4"],\
|
||||
["semver", "npm:7.7.4"],\
|
||||
["tinyglobby", "npm:0.2.15"],\
|
||||
|
|
@ -1675,8 +1686,10 @@ const RAW_RUNTIME_STATE =
|
|||
["prettier", "npm:3.8.1"],\
|
||||
["react", "npm:19.2.4"],\
|
||||
["react-bootstrap", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:2.10.10"],\
|
||||
["react-bootstrap-icons", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:1.11.6"],\
|
||||
["react-dom", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:19.2.4"],\
|
||||
["react-router-dom", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:7.13.1"],\
|
||||
["socket.io-client", "npm:4.8.3"],\
|
||||
["typescript", "patch:typescript@npm%3A5.9.3#optional!builtin<compat/typescript>::version=5.9.3&hash=5786d5"],\
|
||||
["typescript-eslint", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:8.56.1"],\
|
||||
["vite", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:7.3.1"],\
|
||||
|
|
@ -1936,11 +1949,11 @@ const RAW_RUNTIME_STATE =
|
|||
],\
|
||||
"linkType": "SOFT"\
|
||||
}],\
|
||||
["virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3", {\
|
||||
"packageLocation": "./.yarn/__virtual__/debug-virtual-ce2b683fbc/0/cache/debug-npm-4.4.3-0105c6123a-d79136ec6c.zip/node_modules/debug/",\
|
||||
["virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3", {\
|
||||
"packageLocation": "./.yarn/__virtual__/debug-virtual-b7022d90de/0/cache/debug-npm-4.4.3-0105c6123a-d79136ec6c.zip/node_modules/debug/",\
|
||||
"packageDependencies": [\
|
||||
["@types/supports-color", null],\
|
||||
["debug", "virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["ms", "npm:2.1.3"],\
|
||||
["supports-color", null]\
|
||||
],\
|
||||
|
|
@ -1989,6 +2002,29 @@ const RAW_RUNTIME_STATE =
|
|||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["engine.io-client", [\
|
||||
["npm:6.6.6", {\
|
||||
"packageLocation": "./.yarn/cache/engine.io-client-npm-6.6.6-fd14f4b531-805995b57b.zip/node_modules/engine.io-client/",\
|
||||
"packageDependencies": [\
|
||||
["@socket.io/component-emitter", "npm:3.1.2"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["engine.io-client", "npm:6.6.6"],\
|
||||
["engine.io-parser", "npm:5.2.3"],\
|
||||
["ws", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:8.21.3"],\
|
||||
["xmlhttprequest-ssl", "npm:2.1.2"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["engine.io-parser", [\
|
||||
["npm:5.2.3", {\
|
||||
"packageLocation": "./.yarn/cache/engine.io-parser-npm-5.2.3-6dfa36cede-ed4900d8db.zip/node_modules/engine.io-parser/",\
|
||||
"packageDependencies": [\
|
||||
["engine.io-parser", "npm:5.2.3"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["env-paths", [\
|
||||
["npm:2.2.1", {\
|
||||
"packageLocation": "./.yarn/cache/env-paths-npm-2.2.1-7c7577428c-285325677b.zip/node_modules/env-paths/",\
|
||||
|
|
@ -2078,7 +2114,7 @@ const RAW_RUNTIME_STATE =
|
|||
["ajv", "npm:6.14.0"],\
|
||||
["chalk", "npm:4.1.2"],\
|
||||
["cross-spawn", "npm:7.0.6"],\
|
||||
["debug", "virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["escape-string-regexp", "npm:4.0.0"],\
|
||||
["eslint", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:9.39.3"],\
|
||||
["eslint-scope", "npm:8.4.0"],\
|
||||
|
|
@ -2457,7 +2493,7 @@ const RAW_RUNTIME_STATE =
|
|||
"packageLocation": "./.yarn/cache/http-proxy-agent-npm-7.0.2-643ed7cc33-4207b06a45.zip/node_modules/http-proxy-agent/",\
|
||||
"packageDependencies": [\
|
||||
["agent-base", "npm:7.1.4"],\
|
||||
["debug", "virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["http-proxy-agent", "npm:7.0.2"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
|
|
@ -2468,7 +2504,7 @@ const RAW_RUNTIME_STATE =
|
|||
"packageLocation": "./.yarn/cache/https-proxy-agent-npm-7.0.6-27a95c2690-f729219bc7.zip/node_modules/https-proxy-agent/",\
|
||||
"packageDependencies": [\
|
||||
["agent-base", "npm:7.1.4"],\
|
||||
["debug", "virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["https-proxy-agent", "npm:7.0.6"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
|
|
@ -3225,6 +3261,29 @@ const RAW_RUNTIME_STATE =
|
|||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["react-bootstrap-icons", [\
|
||||
["npm:1.11.6", {\
|
||||
"packageLocation": "./.yarn/cache/react-bootstrap-icons-npm-1.11.6-2dbc39d6ac-4dfd75c980.zip/node_modules/react-bootstrap-icons/",\
|
||||
"packageDependencies": [\
|
||||
["react-bootstrap-icons", "npm:1.11.6"]\
|
||||
],\
|
||||
"linkType": "SOFT"\
|
||||
}],\
|
||||
["virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:1.11.6", {\
|
||||
"packageLocation": "./.yarn/__virtual__/react-bootstrap-icons-virtual-ffeae68cb7/0/cache/react-bootstrap-icons-npm-1.11.6-2dbc39d6ac-4dfd75c980.zip/node_modules/react-bootstrap-icons/",\
|
||||
"packageDependencies": [\
|
||||
["@types/react", "npm:19.2.14"],\
|
||||
["prop-types", "npm:15.8.1"],\
|
||||
["react", "npm:19.2.4"],\
|
||||
["react-bootstrap-icons", "virtual:ae939b5bf1c4da31987d1d461851d6cc956667f76e9d6d3a45643e06af20bf533b9bcec6bab70ed0ca795aebf9ce43b3ed74bd20004783b74b2a0cc963cd86b8#npm:1.11.6"]\
|
||||
],\
|
||||
"packagePeers": [\
|
||||
"@types/react",\
|
||||
"react"\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["react-dom", [\
|
||||
["npm:19.2.4", {\
|
||||
"packageLocation": "./.yarn/cache/react-dom-npm-19.2.4-4921ae503e-f0c63f1794.zip/node_modules/react-dom/",\
|
||||
|
|
@ -3485,6 +3544,30 @@ const RAW_RUNTIME_STATE =
|
|||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["socket.io-client", [\
|
||||
["npm:4.8.3", {\
|
||||
"packageLocation": "./.yarn/cache/socket.io-client-npm-4.8.3-6800638250-76c0d86de0.zip/node_modules/socket.io-client/",\
|
||||
"packageDependencies": [\
|
||||
["@socket.io/component-emitter", "npm:3.1.2"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["engine.io-client", "npm:6.6.6"],\
|
||||
["socket.io-client", "npm:4.8.3"],\
|
||||
["socket.io-parser", "npm:4.2.7"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["socket.io-parser", [\
|
||||
["npm:4.2.7", {\
|
||||
"packageLocation": "./.yarn/cache/socket.io-parser-npm-4.2.7-0fe17183fd-16a5579718.zip/node_modules/socket.io-parser/",\
|
||||
"packageDependencies": [\
|
||||
["@socket.io/component-emitter", "npm:3.1.2"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["socket.io-parser", "npm:4.2.7"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["socks", [\
|
||||
["npm:2.8.7", {\
|
||||
"packageLocation": "./.yarn/cache/socks-npm-2.8.7-d1d20aae19-2805a43a1c.zip/node_modules/socks/",\
|
||||
|
|
@ -3501,7 +3584,7 @@ const RAW_RUNTIME_STATE =
|
|||
"packageLocation": "./.yarn/cache/socks-proxy-agent-npm-8.0.5-24d77a90dc-5d2c6cecba.zip/node_modules/socks-proxy-agent/",\
|
||||
"packageDependencies": [\
|
||||
["agent-base", "npm:7.1.4"],\
|
||||
["debug", "virtual:85d5d916b6a745b2f8de0d4b1704b7084bdd4f7573c1ef5d1c877f2c866045a9b29fe2bc752d1b73e531c378a0518dd3f9fa187b31427fb9bacbe34b14715dde#npm:4.4.3"],\
|
||||
["debug", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:4.4.3"],\
|
||||
["socks", "npm:2.8.7"],\
|
||||
["socks-proxy-agent", "npm:8.0.5"]\
|
||||
],\
|
||||
|
|
@ -3862,6 +3945,41 @@ const RAW_RUNTIME_STATE =
|
|||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["ws", [\
|
||||
["npm:8.21.3", {\
|
||||
"packageLocation": "./.yarn/cache/ws-npm-8.21.3-63c47e1f60-7b28dc2863.zip/node_modules/ws/",\
|
||||
"packageDependencies": [\
|
||||
["ws", "npm:8.21.3"]\
|
||||
],\
|
||||
"linkType": "SOFT"\
|
||||
}],\
|
||||
["virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:8.21.3", {\
|
||||
"packageLocation": "./.yarn/__virtual__/ws-virtual-097af440a8/0/cache/ws-npm-8.21.3-63c47e1f60-7b28dc2863.zip/node_modules/ws/",\
|
||||
"packageDependencies": [\
|
||||
["@types/bufferutil", null],\
|
||||
["@types/utf-8-validate", null],\
|
||||
["bufferutil", null],\
|
||||
["utf-8-validate", null],\
|
||||
["ws", "virtual:fd14f4b531a5a95a85dc33ff712d35b53c356fa12f6734083978806651903eae60196105e71a7d037cf3aeffe0d9c55861ee577971d38735aba6ad2f7a34a45a#npm:8.21.3"]\
|
||||
],\
|
||||
"packagePeers": [\
|
||||
"@types/bufferutil",\
|
||||
"@types/utf-8-validate",\
|
||||
"bufferutil",\
|
||||
"utf-8-validate"\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["xmlhttprequest-ssl", [\
|
||||
["npm:2.1.2", {\
|
||||
"packageLocation": "./.yarn/cache/xmlhttprequest-ssl-npm-2.1.2-7d8e3817bc-70d6086932.zip/node_modules/xmlhttprequest-ssl/",\
|
||||
"packageDependencies": [\
|
||||
["xmlhttprequest-ssl", "npm:2.1.2"]\
|
||||
],\
|
||||
"linkType": "HARD"\
|
||||
}]\
|
||||
]],\
|
||||
["yallist", [\
|
||||
["npm:3.1.1", {\
|
||||
"packageLocation": "./.yarn/cache/yallist-npm-3.1.1-a568a556b4-c66a5c46bc.zip/node_modules/yallist/",\
|
||||
|
|
@ -4519,7 +4637,7 @@ async function copyFileViaIndex(
|
|||
const isIndexModified = indexStat?.mtimeMs !== defaultTimeMs;
|
||||
if (isDestinationHardlinkedFromIndex) {
|
||||
if (isIndexModified && linkStrategy.autoRepair) {
|
||||
atomicBehavior = 0 /* Lock */;
|
||||
atomicBehavior = 0; /* Lock */
|
||||
indexStat = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -4739,7 +4857,7 @@ class CustomStatWatcher extends events.EventEmitter {
|
|||
fakeFs;
|
||||
path;
|
||||
bigint;
|
||||
status = "ready" /* Ready */;
|
||||
status = "ready"; /* Ready */
|
||||
changeListeners = /* @__PURE__ */ new Map();
|
||||
lastStats;
|
||||
startTimeout = null;
|
||||
|
|
@ -4757,7 +4875,7 @@ class CustomStatWatcher extends events.EventEmitter {
|
|||
}
|
||||
start() {
|
||||
assertStatus(this.status, "ready" /* Ready */);
|
||||
this.status = "running" /* Running */;
|
||||
this.status = "running"; /* Running */
|
||||
this.startTimeout = setTimeout(() => {
|
||||
this.startTimeout = null;
|
||||
if (!this.fakeFs.existsSync(this.path)) {
|
||||
|
|
@ -4767,7 +4885,7 @@ class CustomStatWatcher extends events.EventEmitter {
|
|||
}
|
||||
stop() {
|
||||
assertStatus(this.status, "running" /* Running */);
|
||||
this.status = "stopped" /* Stopped */;
|
||||
this.status = "stopped"; /* Stopped */
|
||||
if (this.startTimeout !== null) {
|
||||
clearTimeout(this.startTimeout);
|
||||
this.startTimeout = null;
|
||||
|
|
@ -8234,7 +8352,7 @@ var libzipSync = { exports: {} };
|
|||
function UTF8ToString(ptr, maxBytesToRead) {
|
||||
if (!ptr) return "";
|
||||
var maxPtr = ptr + maxBytesToRead;
|
||||
for (var end = ptr; !(end >= maxPtr) && HEAPU8[end]; ) ++end;
|
||||
for (var end = ptr; !(end >= maxPtr) && HEAPU8[end];) ++end;
|
||||
return UTF8Decoder.decode(HEAPU8.subarray(ptr, end));
|
||||
}
|
||||
function stringToUTF8Array(str, heap, outIdx, maxBytesToWrite) {
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ async function copyFileViaIndex(
|
|||
const isIndexModified = indexStat?.mtimeMs !== defaultTimeMs;
|
||||
if (isDestinationHardlinkedFromIndex) {
|
||||
if (isIndexModified && linkStrategy.autoRepair) {
|
||||
atomicBehavior = 0 /* Lock */;
|
||||
atomicBehavior = 0; /* Lock */
|
||||
indexStat = null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
BIN
.yarn/cache/@socket.io-component-emitter-npm-3.1.2-bc4133d33f-c4242bad66.zip
vendored
Normal file
BIN
.yarn/cache/@socket.io-component-emitter-npm-3.1.2-bc4133d33f-c4242bad66.zip
vendored
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -20,8 +20,10 @@
|
|||
"prettier": "^3.8.1",
|
||||
"react": "^19.2.0",
|
||||
"react-bootstrap": "^2.10.10",
|
||||
"react-bootstrap-icons": "^1.11.6",
|
||||
"react-dom": "^19.2.0",
|
||||
"react-router-dom": "^7.13.1",
|
||||
"socket.io-client": "^4.8.3",
|
||||
"yaml": "^2.8.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
11
src/App.tsx
11
src/App.tsx
|
|
@ -12,8 +12,9 @@ import { useState } from "react";
|
|||
import { createBrowserRouter, RouterProvider } from "react-router-dom";
|
||||
import { Provider as JotaiProvider } from "jotai";
|
||||
import { Home } from "./Home.tsx";
|
||||
import { Autonomy } from "./Autonomy.tsx";
|
||||
import { Video } from "./Video.tsx";
|
||||
import { Version } from "./Version.tsx";
|
||||
import { Login } from "./Login.tsx";
|
||||
import "./App.css";
|
||||
|
||||
function App() {
|
||||
|
|
@ -40,8 +41,12 @@ const router = createBrowserRouter([
|
|||
element: <Version />,
|
||||
},
|
||||
{
|
||||
path: "/autonomy",
|
||||
element: <Autonomy />,
|
||||
path: "/video",
|
||||
element: <Video />,
|
||||
},
|
||||
{
|
||||
path: "/login",
|
||||
element: <Login />,
|
||||
},
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
//
|
||||
// Copyright 2026 James Pace
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
// defined by the Mozilla Public License, v. 2.0.
|
||||
//
|
||||
import { AppNav, Footer } from "./AppNav.tsx";
|
||||
import { Container, Row, Col, Image, Card } from "react-bootstrap";
|
||||
import { atom, useAtomValue } from "jotai";
|
||||
import { atomWithQuery } from "jotai-tanstack-query";
|
||||
import { WebRTCVideo } from "mediamtx-webrtc-react";
|
||||
|
||||
const statusStringQuery = async () => {
|
||||
const resp = await fetch("api/status");
|
||||
if (!resp.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
return resp.json();
|
||||
};
|
||||
const statusStringQueryAtom = atomWithQuery(() => ({
|
||||
queryKey: ["status_string"],
|
||||
queryFn: statusStringQuery,
|
||||
refetchInterval: 500, // 0.5s
|
||||
}));
|
||||
const statusStringAtom = atom((get) => {
|
||||
const response = get(statusStringQueryAtom);
|
||||
if (response.isPending || response.isError || !response.data.status) {
|
||||
return "N/A";
|
||||
}
|
||||
return response.data.message;
|
||||
});
|
||||
|
||||
const latLongQuery = async () => {
|
||||
const resp = await fetch("api/position");
|
||||
if (!resp.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
return resp.json();
|
||||
};
|
||||
const latLongQueryAtom = atomWithQuery(() => ({
|
||||
queryKey: ["latlong"],
|
||||
queryFn: latLongQuery,
|
||||
refetchInterval: 500, // 0.5s
|
||||
}));
|
||||
const latLongAtom = atom((get) => {
|
||||
const response = get(latLongQueryAtom);
|
||||
if (response.isPending || response.isError || !response.data.status) {
|
||||
return "N/A";
|
||||
}
|
||||
return `(${response.data.latitude}, ${response.data.longitude})`;
|
||||
});
|
||||
|
||||
export function Autonomy() {
|
||||
const statusString = useAtomValue(statusStringAtom);
|
||||
const latLong = useAtomValue(latLongAtom);
|
||||
|
||||
const imageStreamURI = "http://" + window.location.hostname + ":8889/image/whep";
|
||||
|
||||
return (
|
||||
<div>
|
||||
<AppNav />
|
||||
<Container className="vert-padded">
|
||||
<Card className="padded">
|
||||
<Row>
|
||||
<Col lg={8}>
|
||||
<WebRTCVideo
|
||||
url={ imageStreamURI }
|
||||
controls
|
||||
autoPlay
|
||||
style={{ width: "100%", maxWidth: "800px" }}
|
||||
/>
|
||||
</Col>
|
||||
<Col lg={4}>
|
||||
<p>Status:</p>
|
||||
<pre>{statusString}</pre>
|
||||
<p>Latitude, Longitude:</p>
|
||||
<pre>{latLong}</pre>
|
||||
</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
</Container>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
89
src/Home.tsx
89
src/Home.tsx
|
|
@ -8,21 +8,98 @@
|
|||
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
// defined by the Mozilla Public License, v. 2.0.
|
||||
//
|
||||
import { AppNav, Footer } from "./AppNav.tsx";
|
||||
import { AppNav, Footer } from "./components/AppNav.tsx";
|
||||
import { Container, Row, Col, Image, Card } from "react-bootstrap";
|
||||
import { atom, useAtomValue } from "jotai";
|
||||
import { atomWithQuery } from "jotai-tanstack-query";
|
||||
import { DiagnosticsCard } from "./components/DiagnosticsCard.tsx";
|
||||
|
||||
const statusStringQuery = async () => {
|
||||
const resp = await fetch("api/status");
|
||||
if (!resp.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
return resp.json();
|
||||
};
|
||||
const statusStringQueryAtom = atomWithQuery(() => ({
|
||||
queryKey: ["status_string"],
|
||||
queryFn: statusStringQuery,
|
||||
refetchInterval: 500, // 0.5s
|
||||
}));
|
||||
const statusStringAtom = atom((get) => {
|
||||
const response = get(statusStringQueryAtom);
|
||||
if (response.isPending || response.isError || !response.data.status) {
|
||||
return "N/A";
|
||||
}
|
||||
return response.data.message;
|
||||
});
|
||||
|
||||
const uptimeQuery = async () => {
|
||||
const resp = await fetch("api/uptime");
|
||||
if (!resp.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
return resp.json();
|
||||
};
|
||||
const uptimeQueryAtom = atomWithQuery(() => ({
|
||||
queryKey: ["uptime"],
|
||||
queryFn: uptimeQuery,
|
||||
refetchInterval: 1000, // 1s
|
||||
}));
|
||||
const uptimeAtom = atom((get) => {
|
||||
const response = get(uptimeQueryAtom);
|
||||
if (response.isPending || response.isError) {
|
||||
return "N/A";
|
||||
}
|
||||
return response.data.uptime.toFixed(1);
|
||||
});
|
||||
|
||||
function StatusCard() {
|
||||
const statusString = useAtomValue(statusStringAtom);
|
||||
return (
|
||||
<Card className="padded">
|
||||
<Row>
|
||||
<p>Status:</p>
|
||||
</Row>
|
||||
<Row>
|
||||
<p>{statusString}</p>
|
||||
</Row>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
function UptimeCard() {
|
||||
const uptime = useAtomValue(uptimeAtom);
|
||||
return (
|
||||
<Card className="padded">
|
||||
<Row>
|
||||
<p>Uptime:</p>
|
||||
</Row>
|
||||
<Row>
|
||||
<p>{uptime}s</p>
|
||||
</Row>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export function Home() {
|
||||
return (
|
||||
<div>
|
||||
<AppNav />
|
||||
<Container className="vert-padded">
|
||||
<Card className="padded">
|
||||
<Row>
|
||||
<p>Hello World!</p>
|
||||
</Row>
|
||||
</Card>
|
||||
<Row>
|
||||
<Col>
|
||||
<UptimeCard />
|
||||
</Col>
|
||||
<Col>
|
||||
<StatusCard />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row className="vert-padded">
|
||||
<Col>
|
||||
<DiagnosticsCard />
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
<Footer />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// Copyright 2026 James Pace
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
// defined by the Mozilla Public License, v. 2.0.
|
||||
//
|
||||
import { Container, Row, Col, Card, Button, Form } from "react-bootstrap";
|
||||
import { atom, useAtomValue } from "jotai";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
export function Login() {
|
||||
return (
|
||||
<div>
|
||||
<Container className="vert-padded">
|
||||
<LoginForm />
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function LoginForm() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const onSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
console.log(event.target);
|
||||
const formEntries = new FormData(event.target);
|
||||
const formData = Object.fromEntries(formEntries);
|
||||
console.log(formData);
|
||||
|
||||
const resp = await fetch("/api/login", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(formData),
|
||||
});
|
||||
if (resp.redirected) {
|
||||
navigate("/");
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Form onSubmit={onSubmit}>
|
||||
<Form.Group controlId="passwordForm">
|
||||
<Form.Label>Password</Form.Label>
|
||||
<Form.Control name="password" type="password" />
|
||||
</Form.Group>
|
||||
|
||||
<Button type="submit">Submit</Button>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
// defined by the Mozilla Public License, v. 2.0.
|
||||
//
|
||||
import { AppNav, Footer } from "./AppNav.tsx";
|
||||
import { AppNav, Footer } from "./components/AppNav.tsx";
|
||||
import { Container, Row, Col, Card } from "react-bootstrap";
|
||||
import { atom, useAtomValue } from "jotai";
|
||||
import { atomWithQuery } from "jotai-tanstack-query";
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// Copyright 2026 James Pace
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
// defined by the Mozilla Public License, v. 2.0.
|
||||
//
|
||||
import { AppNav, Footer } from "./components/AppNav.tsx";
|
||||
import { Container, Row, Col, Image, Card } from "react-bootstrap";
|
||||
import { WebRTCVideo } from "mediamtx-webrtc-react";
|
||||
|
||||
export function Video() {
|
||||
const streamName = "image";
|
||||
const imageStreamURI =
|
||||
"http://" + window.location.hostname + ":8889/" + streamName + "/whep";
|
||||
|
||||
return (
|
||||
<div>
|
||||
<AppNav />
|
||||
<Container className="vert-padded">
|
||||
<Card className="padded">
|
||||
<Row>
|
||||
<Col lg={8}>
|
||||
<WebRTCVideo
|
||||
url={imageStreamURI}
|
||||
controls
|
||||
autoPlay
|
||||
style={{ width: "100%", maxWidth: "800px" }}
|
||||
/>
|
||||
</Col>
|
||||
<Col lg={4}>Showing stream: "{streamName}".</Col>
|
||||
</Row>
|
||||
</Card>
|
||||
</Container>
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -24,12 +24,12 @@ export function AppNav() {
|
|||
<Nav.Link as={Link} to="/">
|
||||
Home
|
||||
</Nav.Link>
|
||||
<Nav.Link as={Link} to="/video">
|
||||
Video
|
||||
</Nav.Link>
|
||||
<Nav.Link as={Link} to="/version">
|
||||
Version
|
||||
</Nav.Link>
|
||||
<Nav.Link as={Link} to="/autonomy">
|
||||
Autonomy
|
||||
</Nav.Link>
|
||||
</Nav>
|
||||
</Navbar.Collapse>
|
||||
</Container>
|
||||
|
|
@ -0,0 +1,196 @@
|
|||
import React, { useState } from "react";
|
||||
import { Button, ListGroup, Collapse } from "react-bootstrap";
|
||||
import {
|
||||
Dash,
|
||||
ChevronDown,
|
||||
ChevronRight,
|
||||
CircleFill,
|
||||
} from "react-bootstrap-icons";
|
||||
import { Container, Row, Col, Table, Card } from "react-bootstrap";
|
||||
import { atom, useAtomValue } from "jotai";
|
||||
import { atomWithQuery } from "jotai-tanstack-query";
|
||||
|
||||
const diagQueryFn = async () => {
|
||||
const resp = await fetch("api/diagnostics");
|
||||
if (!resp.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
return resp.json();
|
||||
};
|
||||
|
||||
const diagQueryAtom = atomWithQuery(() => ({
|
||||
queryKey: ["diagnostics"],
|
||||
queryFn: diagQueryFn,
|
||||
}));
|
||||
|
||||
const diagAtom = atom((get) => {
|
||||
const diag = get(diagQueryAtom);
|
||||
if (diag.isPending) {
|
||||
return "Loading...";
|
||||
}
|
||||
if (diag.isError) {
|
||||
return "Error loading!";
|
||||
}
|
||||
if (!diag.data.status) {
|
||||
return "Failed to get diagnostic information.";
|
||||
}
|
||||
return diag.data.message;
|
||||
});
|
||||
|
||||
export function DiagnosticsCard() {
|
||||
const diagnostics = useAtomValue(diagAtom);
|
||||
|
||||
const diagContent = () => {
|
||||
if (typeof diagnostics === "string" || diagnostics instanceof String) {
|
||||
return <pre> {diagnostics} </pre>;
|
||||
}
|
||||
return <TreeView data={diagnostics} />;
|
||||
};
|
||||
|
||||
return (
|
||||
<Card className="padded">
|
||||
<Card.Title>Diagnostics</Card.Title>
|
||||
<Card.Body>{diagContent()}</Card.Body>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
function TreeView(props: Any) {
|
||||
const data = props.data;
|
||||
return (
|
||||
<ListGroup>
|
||||
{data.children.map((node) => (
|
||||
<SingleNode key={node.id} node={node} />
|
||||
))}
|
||||
</ListGroup>
|
||||
);
|
||||
}
|
||||
|
||||
function LevelIndicator(props: Any) {
|
||||
const level = props.level;
|
||||
if (level == "ERROR") {
|
||||
return <CircleFill color="red" />;
|
||||
}
|
||||
if (level == "WARN") {
|
||||
return <CircleFill color="orange" />;
|
||||
}
|
||||
if (level == "OK") {
|
||||
return <CircleFill color="green" />;
|
||||
}
|
||||
return <CircleFill color="grey" />;
|
||||
}
|
||||
|
||||
function MessageText(props: Any) {
|
||||
if (props.message === "") {
|
||||
return <div></div>;
|
||||
}
|
||||
return <div>Message: {props.message}</div>;
|
||||
}
|
||||
|
||||
function ValuesTable(props: Any) {
|
||||
const values = props.values;
|
||||
if (Object.keys(values).length === 0) {
|
||||
return <div></div>;
|
||||
}
|
||||
return (
|
||||
<Table>
|
||||
<thead>
|
||||
<th>Key</th>
|
||||
<th>Value</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Object.entries(values).map(([key, value]) => (
|
||||
<tr key={key}>
|
||||
<td>{key}</td>
|
||||
<td>{value}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</Table>
|
||||
);
|
||||
}
|
||||
|
||||
function StatusContent(props: Any) {
|
||||
const status = props.status;
|
||||
console.log(status);
|
||||
return (
|
||||
<div>
|
||||
<p>{status.name}</p>
|
||||
<p>
|
||||
<MessageText message={status.message} />
|
||||
</p>
|
||||
<p>
|
||||
<ValuesTable values={status.values} />
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function DirectionIcon(props: Any) {
|
||||
let icon = <ChevronRight />;
|
||||
if (props.isOpen) {
|
||||
icon = <ChevronDown />;
|
||||
}
|
||||
if (!props.hasChildren) {
|
||||
icon = <Dash />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Button variant="link" onClick={props.onClick}>
|
||||
{icon}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
function ChildStatuses(props: Any) {
|
||||
const isOpen = props.isOpen;
|
||||
const node = props.node;
|
||||
return (
|
||||
<Collapse in={isOpen}>
|
||||
<div>
|
||||
<ListGroup>
|
||||
{node.children.map((child) => (
|
||||
<SingleNode key={child.id} node={child} />
|
||||
))}
|
||||
</ListGroup>
|
||||
</div>
|
||||
</Collapse>
|
||||
);
|
||||
}
|
||||
|
||||
function SingleNode(props: Any) {
|
||||
const node = props.node;
|
||||
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const hasChildren = node.children && node.children.length > 0;
|
||||
const openFunction = () => {
|
||||
if (hasChildren) {
|
||||
setIsOpen(!isOpen);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ListGroup.Item>
|
||||
<Container>
|
||||
<Row>
|
||||
<Col xs={1}>
|
||||
<DirectionIcon
|
||||
isOpen={isOpen}
|
||||
hasChildren={hasChildren}
|
||||
onClick={openFunction}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={1}>
|
||||
<LevelIndicator level={node.status.level} />
|
||||
</Col>
|
||||
<Col xs={"auto"}>
|
||||
<StatusContent status={node.status} />
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<ChildStatuses isOpen={isOpen} node={node} />
|
||||
</Row>
|
||||
</Container>
|
||||
</ListGroup.Item>
|
||||
);
|
||||
}
|
||||
88
yarn.lock
88
yarn.lock
|
|
@ -843,6 +843,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@socket.io/component-emitter@npm:~3.1.0":
|
||||
version: 3.1.2
|
||||
resolution: "@socket.io/component-emitter@npm:3.1.2"
|
||||
checksum: 10c0/c4242bad66f67e6f7b712733d25b43cbb9e19a595c8701c3ad99cbeb5901555f78b095e24852f862fffb43e96f1d8552e62def885ca82ae1bb05da3668fd87d7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@swc/helpers@npm:^0.5.0":
|
||||
version: 0.5.19
|
||||
resolution: "@swc/helpers@npm:0.5.19"
|
||||
|
|
@ -1192,8 +1199,10 @@ __metadata:
|
|||
prettier: "npm:^3.8.1"
|
||||
react: "npm:^19.2.0"
|
||||
react-bootstrap: "npm:^2.10.10"
|
||||
react-bootstrap-icons: "npm:^1.11.6"
|
||||
react-dom: "npm:^19.2.0"
|
||||
react-router-dom: "npm:^7.13.1"
|
||||
socket.io-client: "npm:^4.8.3"
|
||||
typescript: "npm:~5.9.3"
|
||||
typescript-eslint: "npm:^8.48.0"
|
||||
vite: "npm:^7.3.1"
|
||||
|
|
@ -1404,7 +1413,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.3":
|
||||
"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4, debug@npm:^4.4.3, debug@npm:~4.4.1":
|
||||
version: 4.4.3
|
||||
resolution: "debug@npm:4.4.3"
|
||||
dependencies:
|
||||
|
|
@ -1447,6 +1456,26 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"engine.io-client@npm:~6.6.1":
|
||||
version: 6.6.6
|
||||
resolution: "engine.io-client@npm:6.6.6"
|
||||
dependencies:
|
||||
"@socket.io/component-emitter": "npm:~3.1.0"
|
||||
debug: "npm:~4.4.1"
|
||||
engine.io-parser: "npm:~5.2.1"
|
||||
ws: "npm:~8.21.0"
|
||||
xmlhttprequest-ssl: "npm:~2.1.1"
|
||||
checksum: 10c0/805995b57b2656f52322004b4d767851b517618b1fcecabf5968c55ce6864c692e594fe3a6ae9284504aa087a5a872b0ea1b76b876dcf4cf866907bd61e9e1dd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"engine.io-parser@npm:~5.2.1":
|
||||
version: 5.2.3
|
||||
resolution: "engine.io-parser@npm:5.2.3"
|
||||
checksum: 10c0/ed4900d8dbef470ab3839ccf3bfa79ee518ea8277c7f1f2759e8c22a48f64e687ea5e474291394d0c94f84054749fd93f3ef0acb51fa2f5f234cc9d9d8e7c536
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"env-paths@npm:^2.2.0":
|
||||
version: 2.2.1
|
||||
resolution: "env-paths@npm:2.2.1"
|
||||
|
|
@ -2484,7 +2513,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"prop-types@npm:^15.6.2, prop-types@npm:^15.8.1":
|
||||
"prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1":
|
||||
version: 15.8.1
|
||||
resolution: "prop-types@npm:15.8.1"
|
||||
dependencies:
|
||||
|
|
@ -2502,6 +2531,17 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-bootstrap-icons@npm:^1.11.6":
|
||||
version: 1.11.6
|
||||
resolution: "react-bootstrap-icons@npm:1.11.6"
|
||||
dependencies:
|
||||
prop-types: "npm:^15.7.2"
|
||||
peerDependencies:
|
||||
react: ">=16.8.6"
|
||||
checksum: 10c0/4dfd75c980a4431032e7d861d52efeb18cb141e00300ae1cf055dcfcb1fd7689991d8b467c38f1103563662bbbd61aaf247093e7c04f6f1ad0aae86feff5047d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-bootstrap@npm:^2.10.10":
|
||||
version: 2.10.10
|
||||
resolution: "react-bootstrap@npm:2.10.10"
|
||||
|
|
@ -2778,6 +2818,28 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"socket.io-client@npm:^4.8.3":
|
||||
version: 4.8.3
|
||||
resolution: "socket.io-client@npm:4.8.3"
|
||||
dependencies:
|
||||
"@socket.io/component-emitter": "npm:~3.1.0"
|
||||
debug: "npm:~4.4.1"
|
||||
engine.io-client: "npm:~6.6.1"
|
||||
socket.io-parser: "npm:~4.2.4"
|
||||
checksum: 10c0/76c0d86de0b636d0bf5011cf3425212c900f43dac632db6eb493816920cd035af7ddd92fea9a106b45eb347405953c0414eb3a5d465b180215e46fc8b61420b3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"socket.io-parser@npm:~4.2.4":
|
||||
version: 4.2.7
|
||||
resolution: "socket.io-parser@npm:4.2.7"
|
||||
dependencies:
|
||||
"@socket.io/component-emitter": "npm:~3.1.0"
|
||||
debug: "npm:~4.4.1"
|
||||
checksum: 10c0/16a5579718b871114ca644d688987dd3cf9292010c949fb083633eefbc1d8fdaf424691d6511d746e5c10f5c88cbd8911cd0b1e807242159f40989be90842b4e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"socks-proxy-agent@npm:^8.0.3":
|
||||
version: 8.0.5
|
||||
resolution: "socks-proxy-agent@npm:8.0.5"
|
||||
|
|
@ -3078,6 +3140,28 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ws@npm:~8.21.0":
|
||||
version: 8.21.3
|
||||
resolution: "ws@npm:8.21.3"
|
||||
peerDependencies:
|
||||
bufferutil: ^4.0.1
|
||||
utf-8-validate: ">=5.0.2"
|
||||
peerDependenciesMeta:
|
||||
bufferutil:
|
||||
optional: true
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
checksum: 10c0/7b28dc2863ea0e2cece68d142a3eee90361021b73f750431e6d8076bb7dede5fdfdb75b3d29534b62f411261147b76b1bc80fb5cc63ab0aabd467280e85b22e0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"xmlhttprequest-ssl@npm:~2.1.1":
|
||||
version: 2.1.2
|
||||
resolution: "xmlhttprequest-ssl@npm:2.1.2"
|
||||
checksum: 10c0/70d60869323e823f473a238f78fd108437edbc3690ecd5859c39c83217080090a18899b272e515769c0d1f518cc64cbed6b6995b23fdd7ba13b297d530b6e631
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"yallist@npm:^3.0.2":
|
||||
version: 3.1.1
|
||||
resolution: "yallist@npm:3.1.1"
|
||||
|
|
|
|||
Loading…
Reference in New Issue