Server details in server dashboard

This commit is contained in:
Narek Amirbekian
2022-03-15 12:01:22 -07:00
parent fa8cd90793
commit 6a9d27ceb4
5 changed files with 164 additions and 103 deletions

View File

@@ -37,6 +37,15 @@ object-assign
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
/** @license React v17.0.2
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.2 /** @license React v17.0.2
* react.production.min.js * react.production.min.js
* *

View File

@@ -43,10 +43,11 @@
"lodash.debounce": "^4.0.8", "lodash.debounce": "^4.0.8",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",
"react": "^17.0.1", "react": "^17.0.1",
"react-bootstrap": "^1.4.0", "react-bootstrap": "^2.1.1",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"react-icons": "^4.1.0", "react-icons": "^4.1.0",
"react-multi-select-component": "^3.0.7", "react-multi-select-component": "^3.0.7",
"react-object-table-viewer": "^1.0.7",
"react-redux": "^7.2.2", "react-redux": "^7.2.2",
"react-router": "^5.2.0", "react-router": "^5.2.0",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
@@ -60,7 +61,6 @@
}, },
"devDependencies": { "devDependencies": {
"@wojtekmaj/enzyme-adapter-react-17": "^0.6.5", "@wojtekmaj/enzyme-adapter-react-17": "^0.6.5",
"sinon": "^13.0.1",
"babel-jest": "^26.6.3", "babel-jest": "^26.6.3",
"enzyme": "^3.11.0", "enzyme": "^3.11.0",
"eslint": "^7.18.0", "eslint": "^7.18.0",
@@ -68,6 +68,7 @@
"eslint-plugin-react": "^7.22.0", "eslint-plugin-react": "^7.22.0",
"identity-obj-proxy": "^3.0.0", "identity-obj-proxy": "^3.0.0",
"jest": "^26.6.3", "jest": "^26.6.3",
"prettier": "^2.2.1" "prettier": "^2.2.1",
"sinon": "^13.0.1"
} }
} }

View File

@@ -4,6 +4,8 @@ import { useSelector, useDispatch } from "react-redux";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { Button, Col, Row, FormControl } from "react-bootstrap"; import { Button, Col, Row, FormControl } from "react-bootstrap";
import ReactObjectTableViewer from "react-object-table-viewer";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { FaSort, FaSortUp, FaSortDown } from "react-icons/fa"; import { FaSort, FaSortUp, FaSortDown } from "react-icons/fa";
@@ -19,6 +21,15 @@ const AccessServerButton = ({ url }) => (
</a> </a>
); );
const ToggleButton = ({ dataTarget }) => {
var [errorAlert, setErrorAlert] = useState(null);
return (
<button data-toggle="collapse" data-target={dataTarget}>
<span className="caret"></span>
</button>
);
};
const ServerDashboard = (props) => { const ServerDashboard = (props) => {
let base_url = window.base_url; let base_url = window.base_url;
// sort methods // sort methods
@@ -189,6 +200,91 @@ const ServerDashboard = (props) => {
); );
}; };
const serverRow = (user, server) => {
const { servers, ...userNoServers } = user;
return [
<tr key={`${user.name}-${server.name}-row`} className="user-row">
<td data-testid="user-row-name">
<span>
<ToggleButton
dataTarget={`#${user.name}-${server.name}-collapse`}
/>{" "}
</span>
{user.name}
</td>
<td data-testid="user-row-admin">{user.admin ? "admin" : ""}</td>
<td data-testid="user-row-server">
{server.name ? (
<p class="text-secondary">{server.name}</p>
) : (
<p style={{ color: "lightgrey" }}>[MAIN]</p>
)}
</td>
<td data-testid="user-row-last-activity">
{server.last_activity ? timeSince(server.last_activity) : "Never"}
</td>
<td data-testid="user-row-server-activity">
{server.started ? (
// Stop Single-user server
<>
<StopServerButton serverName={server.name} userName={user.name} />
<AccessServerButton url={server.url} />
</>
) : (
// Start Single-user server
<>
<StartServerButton
serverName={server.name}
userName={user.name}
style={{ marginRight: 20 }}
/>
<a
href={`${base_url}spawn/${user.name}${
server.name && "/" + server.name
}`}
>
<button
className="btn btn-secondary btn-xs"
style={{ marginRight: 20 }}
>
Spawn Page
</button>
</a>
</>
)}
</td>
<EditUserCell user={user} />
</tr>,
<tr>
<td colSpan={6} style={{ padding: 0 }}>
<div
id={`${user.name}-${server.name}-collapse`}
className="collapse"
colSpan={6}
>
<div style={{ padding: 6 }}>
<ReactObjectTableViewer
className="table-striped table-bordered admin-table-head"
style={{
padding: "3px 6px",
margin: "auto",
}}
keyStyle={{
padding: "4px",
}}
valueStyle={{
padding: "4px",
}}
data={{ user: userNoServers, server: server }}
/>
</div>
</div>
</td>
</tr>,
];
};
let servers = user_data.flatMap((user) => { let servers = user_data.flatMap((user) => {
let userServers = Object.values({ let userServers = Object.values({
"": user.server || {}, "": user.server || {},
@@ -234,7 +330,7 @@ const ServerDashboard = (props) => {
<Link to="/groups">{"> Manage Groups"}</Link> <Link to="/groups">{"> Manage Groups"}</Link>
</Col> </Col>
</Row> </Row>
<table className="table table-striped table-bordered table-hover"> <table className="table table-bordered table-hover">
<thead className="admin-table-head"> <thead className="admin-table-head">
<tr> <tr>
<th id="user-header"> <th id="user-header">
@@ -373,63 +469,7 @@ const ServerDashboard = (props) => {
</Button> </Button>
</td> </td>
</tr> </tr>
{servers.map(([user, server], i) => { {servers.flatMap(([user, server]) => serverRow(user, server))}
server.name = server.name || "";
return (
<tr key={i + "row"} className="user-row">
<td data-testid="user-row-name">{user.name}</td>
<td data-testid="user-row-admin">
{user.admin ? "admin" : ""}
</td>
<td data-testid="user-row-server">
{server.name ? (
<p class="text-secondary">{server.name}</p>
) : (
<p style={{ color: "lightgrey" }}>[MAIN]</p>
)}
</td>
<td data-testid="user-row-last-activity">
{server.last_activity
? timeSince(server.last_activity)
: "Never"}
</td>
<td data-testid="user-row-server-activity">
{server.started ? (
// Stop Single-user server
<>
<StopServerButton
serverName={server.name}
userName={user.name}
/>
<AccessServerButton url={server.url} />
</>
) : (
// Start Single-user server
<>
<StartServerButton
serverName={server.name}
userName={user.name}
/>
<a
href={`${base_url}spawn/${user.name}${
server.name && "/" + server.name
}`}
>
<button
className="btn btn-secondary btn-xs"
style={{ marginRight: 20 }}
>
Spawn Page
</button>
</a>
</>
)}
</td>
<EditUserCell user={user} />
</tr>
);
})}
</tbody> </tbody>
</table> </table>
<PaginationFooter <PaginationFooter

View File

@@ -928,7 +928,7 @@
"@babel/plugin-transform-react-jsx-development" "^7.16.7" "@babel/plugin-transform-react-jsx-development" "^7.16.7"
"@babel/plugin-transform-react-pure-annotations" "^7.16.7" "@babel/plugin-transform-react-pure-annotations" "^7.16.7"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.8", "@babel/runtime@^7.14.0", "@babel/runtime@^7.15.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.16", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.2", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
version "7.17.7" version "7.17.7"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.7.tgz#a5f3328dc41ff39d803f311cfe17703418cf9825" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.7.tgz#a5f3328dc41ff39d803f311cfe17703418cf9825"
integrity sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA== integrity sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA==
@@ -1215,23 +1215,41 @@
"@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/sourcemap-codec" "^1.4.10"
"@popperjs/core@^2.8.6": "@popperjs/core@^2.10.1":
version "2.11.4" version "2.11.4"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.4.tgz#d8c7b8db9226d2d7664553a0741ad7d0397ee503" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.4.tgz#d8c7b8db9226d2d7664553a0741ad7d0397ee503"
integrity sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg== integrity sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg==
"@restart/context@^2.1.4": "@react-aria/ssr@^3.0.1":
version "2.1.4" version "3.1.2"
resolved "https://registry.yarnpkg.com/@restart/context/-/context-2.1.4.tgz#a99d87c299a34c28bd85bb489cb07bfd23149c02" resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.1.2.tgz#665a6fd56385068c7417922af2d0d71b0618e52d"
integrity sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q== integrity sha512-amXY11ImpokvkTMeKRHjsSsG7v1yzzs6yeqArCyBIk60J3Yhgxwx9Cah+Uu/804ATFwqzN22AXIo7SdtIaMP+g==
dependencies:
"@babel/runtime" "^7.6.2"
"@restart/hooks@^0.3.26": "@restart/hooks@^0.4.0", "@restart/hooks@^0.4.5":
version "0.3.27" version "0.4.5"
resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.3.27.tgz#91f356d66d4699a8cd8b3d008402708b6a9dc505" resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.4.5.tgz#e7acbea237bfc9e479970500cf87538b41a1ed02"
integrity sha512-s984xV/EapUIfkjlf8wz9weP2O9TNKR96C68FfMEy2bE69+H4cNv3RD4Mf97lW7Htt7PjZrYTjSC8f3SB9VCXw== integrity sha512-tLGtY0aHeIfT7aPwUkvQuhIy3+q3w4iqmUzFLPlOAf/vNUacLaBt1j/S//jv/dQhenRh8jvswyMojCwmLvJw8A==
dependencies: dependencies:
dequal "^2.0.2" dequal "^2.0.2"
"@restart/ui@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@restart/ui/-/ui-1.0.2.tgz#009a06ae698d624672c5e6a776efd0e8a6017842"
integrity sha512-vKGe0UBJLnbvNAjr8ljlDvphf2HkpjBjXsblmgKPvKdZBDn/mtAz89wmznaomIaEJ9VNoSEY0vA5T5MDi2jIcQ==
dependencies:
"@babel/runtime" "^7.13.16"
"@popperjs/core" "^2.10.1"
"@react-aria/ssr" "^3.0.1"
"@restart/hooks" "^0.4.0"
"@types/warning" "^3.0.0"
dequal "^2.0.2"
dom-helpers "^5.2.0"
prop-types "^15.7.2"
uncontrollable "^7.2.1"
warning "^4.0.3"
"@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.8.3": "@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.8.3":
version "1.8.3" version "1.8.3"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d"
@@ -1399,7 +1417,7 @@
"@types/react" "*" "@types/react" "*"
hoist-non-react-statics "^3.3.0" hoist-non-react-statics "^3.3.0"
"@types/invariant@^2.2.33": "@types/invariant@^2.2.35":
version "2.2.35" version "2.2.35"
resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.35.tgz#cd3ebf581a6557452735688d8daba6cf0bd5a3be" resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.35.tgz#cd3ebf581a6557452735688d8daba6cf0bd5a3be"
integrity sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg== integrity sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg==
@@ -1456,7 +1474,7 @@
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17"
integrity sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA== integrity sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA==
"@types/prop-types@*", "@types/prop-types@^15.7.3": "@types/prop-types@*", "@types/prop-types@^15.7.4":
version "15.7.4" version "15.7.4"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ== integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
@@ -1478,7 +1496,7 @@
hoist-non-react-statics "^3.3.0" hoist-non-react-statics "^3.3.0"
redux "^4.0.0" redux "^4.0.0"
"@types/react-transition-group@^4.4.1": "@types/react-transition-group@^4.4.4":
version "4.4.4" version "4.4.4"
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e"
integrity sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug== integrity sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==
@@ -6167,30 +6185,29 @@ raw-body@2.4.3:
iconv-lite "0.4.24" iconv-lite "0.4.24"
unpipe "1.0.0" unpipe "1.0.0"
react-bootstrap@^1.4.0: react-bootstrap@^2.1.1:
version "1.6.4" version "2.2.1"
resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-1.6.4.tgz#94d5d2422e26bba277656d3529128e14f838b7ca" resolved "https://registry.yarnpkg.com/react-bootstrap/-/react-bootstrap-2.2.1.tgz#2a6ad0931e9367882ec3fc88a70ed0b8ace90b26"
integrity sha512-z3BhBD4bEZuLP8VrYqAD7OT7axdcSkkyvWBWnS2U/4MhyabUihrUyucPWkan7aMI1XIHbmH4LCpEtzWGfx/yfA== integrity sha512-x8lpVQflsbevphuWbTnTNCatcbKyPJNrP2WyQ1MJYmFEcVjbTbai1yZhdlXr0QUxLQLxA8g5hQWb5TwJtaZoCA==
dependencies: dependencies:
"@babel/runtime" "^7.14.0" "@babel/runtime" "^7.17.2"
"@restart/context" "^2.1.4" "@restart/hooks" "^0.4.5"
"@restart/hooks" "^0.3.26" "@restart/ui" "^1.0.2"
"@types/invariant" "^2.2.33" "@types/invariant" "^2.2.35"
"@types/prop-types" "^15.7.3" "@types/prop-types" "^15.7.4"
"@types/react" ">=16.14.8" "@types/react" ">=16.14.8"
"@types/react-transition-group" "^4.4.1" "@types/react-transition-group" "^4.4.4"
"@types/warning" "^3.0.0" "@types/warning" "^3.0.0"
classnames "^2.3.1" classnames "^2.3.1"
dom-helpers "^5.2.1" dom-helpers "^5.2.1"
invariant "^2.2.4" invariant "^2.2.4"
prop-types "^15.7.2" prop-types "^15.8.1"
prop-types-extra "^1.1.0" prop-types-extra "^1.1.0"
react-overlays "^5.1.1" react-transition-group "^4.4.2"
react-transition-group "^4.4.1"
uncontrollable "^7.2.1" uncontrollable "^7.2.1"
warning "^4.0.3" warning "^4.0.3"
react-dom@^17.0.1: react-dom@17.0.2, react-dom@^17.0.1:
version "17.0.2" version "17.0.2"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
@@ -6226,19 +6243,13 @@ react-multi-select-component@^3.0.7:
dependencies: dependencies:
goober "^2.0.30" goober "^2.0.30"
react-overlays@^5.1.1: react-object-table-viewer@^1.0.7:
version "5.1.1" version "1.0.7"
resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-5.1.1.tgz#2e7cf49744b56537c7828ccb94cfc63dd778ae4f" resolved "https://registry.yarnpkg.com/react-object-table-viewer/-/react-object-table-viewer-1.0.7.tgz#31816021fa4526641c6b66bd9433ec9b78c2e472"
integrity sha512-eCN2s2/+GVZzpnId4XVWtvDPYYBD2EtOGP74hE+8yDskPzFy9+pV1H3ZZihxuRdEbQzzacySaaDkR7xE0ydl4Q== integrity sha512-OezCet8+BmEdJJHO5WGPFPRWXxw4Ls6HsV4Uh1kRPlmRXLOTNqWt/ZHmH8NhTl1BA9HkdhEegKVqc2b61wDMLg==
dependencies: dependencies:
"@babel/runtime" "^7.13.8" react "^17.0.2"
"@popperjs/core" "^2.8.6" react-dom "17.0.2"
"@restart/hooks" "^0.3.26"
"@types/warning" "^3.0.0"
dom-helpers "^5.2.0"
prop-types "^15.7.2"
uncontrollable "^7.2.1"
warning "^4.0.3"
react-redux@^7.2.2: react-redux@^7.2.2:
version "7.2.6" version "7.2.6"
@@ -6299,7 +6310,7 @@ react-test-renderer@^17.0.0:
react-shallow-renderer "^16.13.1" react-shallow-renderer "^16.13.1"
scheduler "^0.20.2" scheduler "^0.20.2"
react-transition-group@^4.4.1: react-transition-group@^4.4.2:
version "4.4.2" version "4.4.2"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg== integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==
@@ -6309,7 +6320,7 @@ react-transition-group@^4.4.1:
loose-envify "^1.4.0" loose-envify "^1.4.0"
prop-types "^15.6.2" prop-types "^15.6.2"
react@^17.0.1: react@^17.0.1, react@^17.0.2:
version "17.0.2" version "17.0.2"
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==

File diff suppressed because one or more lines are too long