From 161d22fd78ec17145ae70d4a0f5914a68d6ec729 Mon Sep 17 00:00:00 2001 From: Christian Maddox Date: Mon, 28 Oct 2024 13:38:30 -0400 Subject: [PATCH] Revert "revert: React/TS Upgrades (#2268)" This reverts commit d6ef9ecfc3696ab57aee358b8ea70b3f868443d5. --- assets/package-lock.json | 261 ++++++------------ assets/package.json | 18 +- assets/src/apps/admin.tsx | 18 +- assets/src/apps/gl_eink_single.tsx | 35 ++- assets/src/apps/solari.tsx | 35 ++- assets/src/apps/v2/bus_eink.tsx | 81 +++--- assets/src/apps/v2/bus_shelter.tsx | 75 ++--- assets/src/apps/v2/busway.tsx | 71 ++--- assets/src/apps/v2/dup.tsx | 71 ++--- assets/src/apps/v2/elevator.tsx | 50 ++-- assets/src/apps/v2/gl_eink.tsx | 81 +++--- assets/src/apps/v2/pre_fare.tsx | 75 ++--- assets/src/apps/v2/solari_large.tsx | 33 ++- assets/src/components/admin/admin_cells.tsx | 1 - assets/src/components/admin/admin_filters.tsx | 1 - .../components/admin/admin_image_manager.tsx | 9 +- assets/src/components/admin/inspector.tsx | 6 +- assets/src/components/eink/digital_bridge.tsx | 4 +- .../helpers/debug_error_boundary.tsx | 4 +- assets/src/components/v2/dup/viewport.tsx | 4 +- .../src/components/v2/pre_fare/viewport.tsx | 4 +- .../v2/widget_tree_error_boundary.tsx | 24 +- assets/src/util/admin.tsx | 2 +- assets/tsconfig.json | 2 +- 24 files changed, 478 insertions(+), 487 deletions(-) diff --git a/assets/package-lock.json b/assets/package-lock.json index 977f1307f..e271190e9 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -12,13 +12,13 @@ "lodash": "^4.17.21", "moment": "^2.30.1", "moment-timezone": "^0.5.46", - "qrcode.react": "^1.0.1", + "qrcode.react": "^4.0.1", "raven-js": "^3.27.2", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-dropzone": "^11.3.4", - "react-router-dom": "^5.2.0", - "react-table": "^7.7.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-dropzone": "^14.2.9", + "react-router-dom": "^6.27.0", + "react-table": "^7.8.0", "react-transition-group": "^4.4.5", "regenerator-runtime": "^0.13.7", "weak-key": "^1.0.3" @@ -38,9 +38,7 @@ "@sentry/webpack-plugin": "^2.22.6", "@svgr/webpack": "^5.5.0", "@types/lodash": "^4.17.12", - "@types/react": "^17.0.14", - "@types/react-dom": "^17.0.9", - "@types/react-router-dom": "^5.1.8", + "@types/react": "^18.3.11", "@types/webpack-env": "^1.18.4", "babel-loader": "^8.2.2", "concurrently": "^8.2.2", @@ -69,7 +67,7 @@ "terser-webpack-plugin": "^4.2.3", "ts-jest": "^29.1.2", "ts-loader": "^8.3.0", - "typescript": "^4.3.5", + "typescript": "^5.6.3", "typescript-eslint": "^7.8.0", "webpack": "^4.46.0", "webpack-cli": "^4.7.2", @@ -3659,6 +3657,14 @@ "node": ">=10" } }, + "node_modules/@remix-run/router": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.20.0.tgz", + "integrity": "sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@sentry/babel-plugin-component-annotate": { "version": "2.22.6", "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-2.22.6.tgz", @@ -4378,11 +4384,6 @@ "@types/node": "*" } }, - "node_modules/@types/history": { - "version": "4.7.9", - "dev": true, - "license": "MIT" - }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "dev": true, @@ -4439,47 +4440,15 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "17.0.38", + "version": "18.3.11", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz", + "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==", "dev": true, - "license": "MIT", "dependencies": { "@types/prop-types": "*", - "@types/scheduler": "*", "csstype": "^3.0.2" } }, - "node_modules/@types/react-dom": { - "version": "17.0.11", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-router": { - "version": "5.1.17", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/history": "*", - "@types/react": "*" - } - }, - "node_modules/@types/react-router-dom": { - "version": "5.3.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/history": "*", - "@types/react": "*", - "@types/react-router": "*" - } - }, - "node_modules/@types/scheduler": { - "version": "0.16.2", - "dev": true, - "license": "MIT" - }, "node_modules/@types/semver": { "version": "7.5.8", "dev": true, @@ -8441,19 +8410,16 @@ } }, "node_modules/file-selector": { - "version": "0.2.4", - "license": "MIT", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", + "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", "dependencies": { - "tslib": "^2.0.3" + "tslib": "^2.4.0" }, "engines": { - "node": ">= 10" + "node": ">= 12" } }, - "node_modules/file-selector/node_modules/tslib": { - "version": "2.3.1", - "license": "0BSD" - }, "node_modules/file-uri-to-path": { "version": "1.0.0", "dev": true, @@ -9040,18 +9006,6 @@ "node": ">= 0.4" } }, - "node_modules/history": { - "version": "4.10.1", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" - } - }, "node_modules/hmac-drbg": { "version": "1.0.1", "dev": true, @@ -9062,13 +9016,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "license": "BSD-3-Clause", - "dependencies": { - "react-is": "^16.7.0" - } - }, "node_modules/html-escaper": { "version": "2.0.2", "dev": true, @@ -9726,10 +9673,6 @@ "node": ">=4" } }, - "node_modules/isarray": { - "version": "0.0.1", - "license": "MIT" - }, "node_modules/isexe": { "version": "2.0.0", "dev": true, @@ -11763,18 +11706,6 @@ "node": ">=6" } }, - "node_modules/mini-create-react-context": { - "version": "0.4.1", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.1", - "tiny-warning": "^1.0.3" - }, - "peerDependencies": { - "prop-types": "^15.0.0", - "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, "node_modules/mini-css-extract-plugin": { "version": "1.6.2", "dev": true, @@ -12606,14 +12537,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/path-to-regexp": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", - "dependencies": { - "isarray": "0.0.1" - } - }, "node_modules/path-type": { "version": "4.0.0", "dev": true, @@ -13419,20 +13342,13 @@ "teleport": ">=0.2.0" } }, - "node_modules/qr.js": { - "version": "0.0.0", - "license": "MIT" - }, "node_modules/qrcode.react": { - "version": "1.0.1", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-4.0.1.tgz", + "integrity": "sha512-Lpj0tPBn561WiQ3QQWXbkx8xTtB8BZkJeMZWLJIL8iaPBCoWzW1IpCeU3gY5MDqsb0+efCvEGkl9O0naP64crA==", "license": "ISC", - "dependencies": { - "loose-envify": "^1.4.0", - "prop-types": "^15.6.0", - "qr.js": "0.0.0" - }, "peerDependencies": { - "react": "^15.5.3 || ^16.0.0 || ^17.0.0" + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/querystring": { @@ -13490,41 +13406,42 @@ "license": "BSD-2-Clause" }, "node_modules/react": { - "version": "17.0.2", - "license": "MIT", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "17.0.2", - "license": "MIT", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dependencies": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "scheduler": "^0.20.2" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "17.0.2" + "react": "^18.3.1" } }, "node_modules/react-dropzone": { - "version": "11.4.2", - "license": "MIT", + "version": "14.2.9", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.9.tgz", + "integrity": "sha512-jRZsMC7h48WONsOLHcmhyn3cRWJoIPQjPApvt/sJVfnYaB3Qltn025AoRTTJaj4WdmmgmLl6tUQg1s0wOhpodQ==", "dependencies": { - "attr-accept": "^2.2.1", - "file-selector": "^0.2.2", - "prop-types": "^15.7.2" + "attr-accept": "^2.2.2", + "file-selector": "^0.6.0", + "prop-types": "^15.8.1" }, "engines": { - "node": ">= 10" + "node": ">= 10.13" }, "peerDependencies": { - "react": ">= 16.8" + "react": ">= 16.8 || 18.0.0" } }, "node_modules/react-is": { @@ -13532,49 +13449,45 @@ "license": "MIT" }, "node_modules/react-router": { - "version": "5.2.1", - "license": "MIT", + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.27.0.tgz", + "integrity": "sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==", "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "mini-create-react-context": "^0.4.0", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" + "@remix-run/router": "1.20.0" + }, + "engines": { + "node": ">=14.0.0" }, "peerDependencies": { - "react": ">=15" + "react": ">=16.8" } }, "node_modules/react-router-dom": { - "version": "5.3.0", - "license": "MIT", + "version": "6.27.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.27.0.tgz", + "integrity": "sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==", "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.2.1", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" + "@remix-run/router": "1.20.0", + "react-router": "6.27.0" + }, + "engines": { + "node": ">=14.0.0" }, "peerDependencies": { - "react": ">=15" + "react": ">=16.8", + "react-dom": ">=16.8" } }, "node_modules/react-table": { - "version": "7.7.0", - "license": "MIT", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz", + "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "react": "^16.8.3 || ^17.0.0-0" + "react": "^16.8.3 || ^17.0.0-0 || ^18.0.0" } }, "node_modules/react-transition-group": { @@ -13822,10 +13735,6 @@ "node": ">=8" } }, - "node_modules/resolve-pathname": { - "version": "3.0.0", - "license": "MIT" - }, "node_modules/resolve-url": { "version": "0.2.1", "dev": true, @@ -13917,11 +13826,6 @@ "tslib": "^2.1.0" } }, - "node_modules/rxjs/node_modules/tslib": { - "version": "2.6.2", - "dev": true, - "license": "0BSD" - }, "node_modules/safe-array-concat": { "version": "1.1.2", "dev": true, @@ -14067,11 +13971,11 @@ "license": "ISC" }, "node_modules/scheduler": { - "version": "0.20.2", - "license": "MIT", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" + "loose-envify": "^1.1.0" } }, "node_modules/schema-utils": { @@ -15446,14 +15350,6 @@ "dev": true, "license": "MIT" }, - "node_modules/tiny-invariant": { - "version": "1.2.0", - "license": "MIT" - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "license": "MIT" - }, "node_modules/tmpl": { "version": "1.0.5", "dev": true, @@ -15694,6 +15590,11 @@ "node": ">=8" } }, + "node_modules/tslib": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" + }, "node_modules/tty-browserify": { "version": "0.0.0", "dev": true, @@ -15793,7 +15694,9 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "4.9.5", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -15801,7 +15704,7 @@ "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/typescript-eslint": { @@ -16121,10 +16024,6 @@ "node": ">=10.12.0" } }, - "node_modules/value-equal": { - "version": "1.0.1", - "license": "MIT" - }, "node_modules/vm-browserify": { "version": "1.1.2", "dev": true, diff --git a/assets/package.json b/assets/package.json index 223de6575..707fbfc2b 100644 --- a/assets/package.json +++ b/assets/package.json @@ -24,13 +24,13 @@ "lodash": "^4.17.21", "moment": "^2.30.1", "moment-timezone": "^0.5.46", - "qrcode.react": "^1.0.1", + "qrcode.react": "^4.0.1", "raven-js": "^3.27.2", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "react-dropzone": "^11.3.4", - "react-router-dom": "^5.2.0", - "react-table": "^7.7.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-dropzone": "^14.2.9", + "react-router-dom": "^6.27.0", + "react-table": "^7.8.0", "react-transition-group": "^4.4.5", "regenerator-runtime": "^0.13.7", "weak-key": "^1.0.3" @@ -50,9 +50,7 @@ "@sentry/webpack-plugin": "^2.22.6", "@svgr/webpack": "^5.5.0", "@types/lodash": "^4.17.12", - "@types/react": "^17.0.14", - "@types/react-dom": "^17.0.9", - "@types/react-router-dom": "^5.1.8", + "@types/react": "^18.3.11", "@types/webpack-env": "^1.18.4", "babel-loader": "^8.2.2", "concurrently": "^8.2.2", @@ -81,7 +79,7 @@ "terser-webpack-plugin": "^4.2.3", "ts-jest": "^29.1.2", "ts-loader": "^8.3.0", - "typescript": "^4.3.5", + "typescript": "^5.6.3", "typescript-eslint": "^7.8.0", "webpack": "^4.46.0", "webpack-cli": "^4.7.2", diff --git a/assets/src/apps/admin.tsx b/assets/src/apps/admin.tsx index 159c1aec3..2385ef163 100644 --- a/assets/src/apps/admin.tsx +++ b/assets/src/apps/admin.tsx @@ -1,12 +1,12 @@ require("../../css/admin.scss"); import React, { ComponentType } from "react"; -import ReactDOM from "react-dom"; +import { createRoot } from "react-dom/client"; import { BrowserRouter as Router, NavLink, Route, - Switch, + Routes, } from "react-router-dom"; import weakKey from "weak-key"; @@ -51,7 +51,7 @@ const App = (): JSX.Element => { {routes.map((group) => (
{group.map(([path, label]) => ( - + {label} ))} @@ -59,17 +59,17 @@ const App = (): JSX.Element => { ))}
- + {routes.map((group) => group.map(([path, , Component]) => ( - - - + }> )), )} - + ); }; -ReactDOM.render(, document.getElementById("app")); +const container = document.getElementById("app"); +const root = createRoot(container!); +root.render(); diff --git a/assets/src/apps/gl_eink_single.tsx b/assets/src/apps/gl_eink_single.tsx index ee20e4635..9d8d23b3b 100644 --- a/assets/src/apps/gl_eink_single.tsx +++ b/assets/src/apps/gl_eink_single.tsx @@ -4,8 +4,8 @@ initSentry("gl_eink_single"); require("../../css/gl_eink_single.scss"); import React from "react"; -import ReactDOM from "react-dom"; -import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import ScreenContainer, { ScreenLayout, @@ -20,19 +20,26 @@ import { const App = (): JSX.Element => { return ( - - - - - - - - - - - + + } + /> + + } + /> + + } + /> + ); }; -ReactDOM.render(, document.getElementById("app")); +const container = document.getElementById("app"); +const root = createRoot(container!); +root.render(); diff --git a/assets/src/apps/solari.tsx b/assets/src/apps/solari.tsx index 08a327888..43e0790f7 100644 --- a/assets/src/apps/solari.tsx +++ b/assets/src/apps/solari.tsx @@ -7,8 +7,8 @@ initFullstory(); require("../../css/solari.scss"); import React, { useEffect } from "react"; -import ReactDOM from "react-dom"; -import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import ScreenContainer, { ScreenLayout, @@ -25,17 +25,22 @@ const App = (): JSX.Element => { return ( - - - - - - - - - - - + + } + /> + + } + /> + + } + /> + ); }; @@ -57,4 +62,6 @@ const handleWatchdogMessage = (ev: MessageEvent) => { } }; -ReactDOM.render(, document.getElementById("app")); +const container = document.getElementById("app"); +const root = createRoot(container!); +root.render(); diff --git a/assets/src/apps/v2/bus_eink.tsx b/assets/src/apps/v2/bus_eink.tsx index 8c5f8e30c..6443bff69 100644 --- a/assets/src/apps/v2/bus_eink.tsx +++ b/assets/src/apps/v2/bus_eink.tsx @@ -7,8 +7,8 @@ initFullstory(); require("../../../css/bus_eink_v2.scss"); import React from "react"; -import ReactDOM from "react-dom"; -import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import ScreenPage from "Components/v2/screen_page"; import { MappingContext } from "Components/v2/widget"; @@ -93,41 +93,52 @@ const responseMapper: ResponseMapper = (apiResponse) => { const App = (): JSX.Element => { return ( - - - - - - - - - - - - - - - - + - - - - - - - + path="/v2/screen/bus_eink_v2" + element={ + + } + /> + + + + + + + } + /> + + + + + } + /> + + + + + + + } + /> + ); }; -ReactDOM.render(, document.getElementById("app")); +const container = document.getElementById("app"); +const root = createRoot(container!); +root.render(); diff --git a/assets/src/apps/v2/bus_shelter.tsx b/assets/src/apps/v2/bus_shelter.tsx index f3ee9f739..6113afc4f 100644 --- a/assets/src/apps/v2/bus_shelter.tsx +++ b/assets/src/apps/v2/bus_shelter.tsx @@ -7,8 +7,8 @@ initFullstory(); require("../../../css/bus_shelter_v2.scss"); import React from "react"; -import ReactDOM from "react-dom"; -import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import ScreenPage from "Components/v2/screen_page"; import { ResponseMapper, @@ -122,40 +122,47 @@ const getAudioConfig = (): AudioConfig | null => { const App = (): JSX.Element => { return ( - - - - - - - - - - - - - - - + - - - - - - - + path="/v2/screen/bus_shelter_v2" + element={ + + } + /> + + + + + + + + + + + } + /> + + + + + + + } + /> + ); }; -ReactDOM.render(, document.getElementById("app")); +const container = document.getElementById("app"); +const root = createRoot(container!); +root.render(); diff --git a/assets/src/apps/v2/busway.tsx b/assets/src/apps/v2/busway.tsx index 19c56e991..08f516a85 100644 --- a/assets/src/apps/v2/busway.tsx +++ b/assets/src/apps/v2/busway.tsx @@ -7,8 +7,8 @@ initFullstory(); require("../../../css/busway_v2.scss"); import React from "react"; -import ReactDOM from "react-dom"; -import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import ScreenPage from "Components/v2/screen_page"; import { BlinkConfig, @@ -80,38 +80,45 @@ const blinkConfig: BlinkConfig = { const App = (): JSX.Element => { return ( - - - - - - - - - - - - - + - - - - - - - + path="/v2/screen/busway_v2" + element={ + + } + /> + + + + + + + + + } + /> + + + + + + + } + /> + ); }; -ReactDOM.render(, document.getElementById("app")); +const container = document.getElementById("app"); +const root = createRoot(container!); +root.render(); diff --git a/assets/src/apps/v2/dup.tsx b/assets/src/apps/v2/dup.tsx index bda667488..1ca08ad27 100644 --- a/assets/src/apps/v2/dup.tsx +++ b/assets/src/apps/v2/dup.tsx @@ -7,8 +7,8 @@ initFullstory(); require("../../../css/dup_v2.scss"); import React from "react"; -import ReactDOM from "react-dom"; -import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import ScreenPage from "Components/v2/screen_page"; import { MappingContext } from "Components/v2/widget"; @@ -131,38 +131,45 @@ const App = (): JSX.Element => { return ( - - - - - - - - - - - - - + - - - - - - - + path="/v2/screen/dup_v2" + element={ + + } + /> + + + + + + + + + } + /> + + + + + + + } + /> + ); }; -ReactDOM.render(, document.getElementById("app")); +const container = document.getElementById("app"); +const root = createRoot(container!); +root.render(); diff --git a/assets/src/apps/v2/elevator.tsx b/assets/src/apps/v2/elevator.tsx index cea5a1e47..3d47496fc 100644 --- a/assets/src/apps/v2/elevator.tsx +++ b/assets/src/apps/v2/elevator.tsx @@ -7,8 +7,8 @@ initFullstory(); require("../../../css/elevator_v2.scss"); import React from "react"; -import ReactDOM from "react-dom"; -import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import NormalScreen from "Components/v2/elevator/normal_screen"; import EvergreenContent from "Components/v2/evergreen_content"; import ScreenPage from "Components/v2/screen_page"; @@ -30,29 +30,33 @@ const TYPE_TO_COMPONENT = { const App = (): JSX.Element => { return ( - - - - - - - - - + - - - - - + path="/v2/screen/elevator_v2" + element={} + /> + + + + + } + /> + + + + } + /> + ); }; -ReactDOM.render(, document.getElementById("app")); +const container = document.getElementById("app"); +const root = createRoot(container!); +root.render(); diff --git a/assets/src/apps/v2/gl_eink.tsx b/assets/src/apps/v2/gl_eink.tsx index 643bc850c..4516322df 100644 --- a/assets/src/apps/v2/gl_eink.tsx +++ b/assets/src/apps/v2/gl_eink.tsx @@ -7,8 +7,8 @@ initFullstory(); require("../../../css/gl_eink_v2.scss"); import React from "react"; -import ReactDOM from "react-dom"; -import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import ScreenPage from "Components/v2/screen_page"; import { MappingContext } from "Components/v2/widget"; @@ -98,41 +98,52 @@ const responseMapper: ResponseMapper = (apiResponse) => { const App = (): JSX.Element => { return ( - - - - - - - - - - - - - - - - + - - - - - - - + path="/v2/screen/gl_eink_v2" + element={ + + } + /> + + + + + + + } + /> + + + + + } + /> + + + + + + + } + /> + ); }; -ReactDOM.render(, document.getElementById("app")); +const container = document.getElementById("app"); +const root = createRoot(container!); +root.render(); diff --git a/assets/src/apps/v2/pre_fare.tsx b/assets/src/apps/v2/pre_fare.tsx index eff2567e0..20c7eca79 100644 --- a/assets/src/apps/v2/pre_fare.tsx +++ b/assets/src/apps/v2/pre_fare.tsx @@ -7,8 +7,8 @@ initFullstory(); require("../../../css/pre_fare_v2.scss"); import React from "react"; -import ReactDOM from "react-dom"; -import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import ScreenPage from "Components/v2/screen_page"; import { ResponseMapper, @@ -116,40 +116,47 @@ const blinkConfig: BlinkConfig = { const App = (): JSX.Element => { return ( - - - - - - - - - - - - - - - + - - - - - - - + path="/v2/screen/pre_fare_v2" + element={ + + } + /> + + + + + + + + + + + } + /> + + + + + + + } + /> + ); }; -ReactDOM.render(, document.getElementById("app")); +const container = document.getElementById("app"); +const root = createRoot(container!); +root.render(); diff --git a/assets/src/apps/v2/solari_large.tsx b/assets/src/apps/v2/solari_large.tsx index 43605c774..916996c58 100644 --- a/assets/src/apps/v2/solari_large.tsx +++ b/assets/src/apps/v2/solari_large.tsx @@ -4,8 +4,8 @@ initSentry("solari_large"); require("../../../css/solari_large_v2.scss"); import React from "react"; -import ReactDOM from "react-dom"; -import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import ScreenPage from "Components/v2/screen_page"; import { MappingContext } from "Components/v2/widget"; @@ -27,18 +27,25 @@ const TYPE_TO_COMPONENT = { const App = (): JSX.Element => { return ( - - - - - - - - - - + + } + /> + + + + + } + /> + ); }; -ReactDOM.render(, document.getElementById("app")); +const container = document.getElementById("app"); +const root = createRoot(container!); +root.render(); diff --git a/assets/src/components/admin/admin_cells.tsx b/assets/src/components/admin/admin_cells.tsx index 92d88424d..7d86990df 100644 --- a/assets/src/components/admin/admin_cells.tsx +++ b/assets/src/components/admin/admin_cells.tsx @@ -120,7 +120,6 @@ const EditableSelect = ({ disabled={!editable} > {options.map((opt) => ( - // @ts-expect-error diff --git a/assets/src/components/admin/admin_filters.tsx b/assets/src/components/admin/admin_filters.tsx index ebdad4fce..2da9d6b29 100644 --- a/assets/src/components/admin/admin_filters.tsx +++ b/assets/src/components/admin/admin_filters.tsx @@ -36,7 +36,6 @@ const SelectColumnFilter = ({ > {options.map((option, i) => ( - // @ts-expect-error diff --git a/assets/src/components/admin/admin_image_manager.tsx b/assets/src/components/admin/admin_image_manager.tsx index a65f2c762..ca6eaf35c 100644 --- a/assets/src/components/admin/admin_image_manager.tsx +++ b/assets/src/components/admin/admin_image_manager.tsx @@ -107,7 +107,8 @@ const ImageUpload = (): JSX.Element => { }; const onDrop = useCallback( - ([acceptedFile]) => { + (acceptedFiles) => { + const [acceptedFile] = acceptedFiles; if (acceptedFile) { const fileWithPreview = Object.assign(acceptedFile, { preview: URL.createObjectURL(acceptedFile), @@ -122,7 +123,11 @@ const ImageUpload = (): JSX.Element => { const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop, - accept: ["image/png", "image/gif", "image/svg+xml"], + accept: { + "image/png": [".png"], + "image/gif": [".gif"], + "image/svg+xml": [".svg", ".xml"], + }, multiple: false, maxSize: 20000000, }); diff --git a/assets/src/components/admin/inspector.tsx b/assets/src/components/admin/inspector.tsx index d21aacb7a..26070403d 100644 --- a/assets/src/components/admin/inspector.tsx +++ b/assets/src/components/admin/inspector.tsx @@ -6,7 +6,7 @@ import React, { useRef, useState, } from "react"; -import { useHistory, useLocation } from "react-router-dom"; +import { useNavigate, useLocation } from "react-router-dom"; import AdminForm from "./admin_form"; @@ -145,13 +145,13 @@ const ScreenSelector: ComponentType<{ isVariantEnabled, setIsVariantEnabled, }) => { - const history = useHistory(); + const navigate = useNavigate(); const { pathname, search } = useLocation(); const navigateToScreen = (id) => { const params = new URLSearchParams(search); params.set("id", id); - history.push({ pathname, search: params.toString() }); + navigate({ pathname, search: params.toString() }); }; const screensByType: Record = Object.entries( diff --git a/assets/src/components/eink/digital_bridge.tsx b/assets/src/components/eink/digital_bridge.tsx index dd7ea75b1..ef781096b 100644 --- a/assets/src/components/eink/digital_bridge.tsx +++ b/assets/src/components/eink/digital_bridge.tsx @@ -1,4 +1,4 @@ -import QRCode from "qrcode.react"; +import { QRCodeSVG } from "qrcode.react"; import React from "react"; import { imagePath } from "Util/util"; @@ -20,7 +20,7 @@ const DigitalBridge = ({ stopId }): JSX.Element => {
- { public static getDerivedStateFromError(_error: Error) { return { hasError: true }; } diff --git a/assets/src/components/v2/dup/viewport.tsx b/assets/src/components/v2/dup/viewport.tsx index 8163fbdb2..dcc7438f7 100644 --- a/assets/src/components/v2/dup/viewport.tsx +++ b/assets/src/components/v2/dup/viewport.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { PropsWithChildren } from "react"; import { getRotationIndex } from "Util/outfront"; @@ -8,7 +8,7 @@ import { getRotationIndex } from "Util/outfront"; * If the param is missing, this will show the full * screen content (5760px x 1080px). */ -const Viewport: React.ComponentType = ({ children }) => { +const Viewport = ({ children }: PropsWithChildren) => { let viewportClassName = "dup-screen-viewport"; let shifterClassName = "dup-shifter"; switch (getRotationIndex()) { diff --git a/assets/src/components/v2/pre_fare/viewport.tsx b/assets/src/components/v2/pre_fare/viewport.tsx index b07cf7195..9d374b15e 100644 --- a/assets/src/components/v2/pre_fare/viewport.tsx +++ b/assets/src/components/v2/pre_fare/viewport.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { PropsWithChildren } from "react"; import { getScreenSide } from "Util/util"; @@ -8,7 +8,7 @@ import { getScreenSide } from "Util/util"; * If the param is missing, this will show the full * screen content (2160px x 1920px). */ -const Viewport: React.ComponentType = ({ children }) => { +const Viewport = ({ children }: PropsWithChildren) => { let viewportClassName = "pre-fare-screen-viewport"; let shifterClassName = "pre-fare-shifter"; switch (getScreenSide()) { diff --git a/assets/src/components/v2/widget_tree_error_boundary.tsx b/assets/src/components/v2/widget_tree_error_boundary.tsx index dd6f0d633..e614451fb 100644 --- a/assets/src/components/v2/widget_tree_error_boundary.tsx +++ b/assets/src/components/v2/widget_tree_error_boundary.tsx @@ -1,5 +1,5 @@ -import React, { ErrorInfo, useContext } from "react"; -import { RouteComponentProps, withRouter } from "react-router-dom"; +import React, { ErrorInfo, PropsWithChildren, useContext } from "react"; +import { useLocation, useNavigate, useParams } from "react-router-dom"; import getCsrfToken from "Util/csrf"; import { getDataset } from "Util/dataset"; import { isRealScreen } from "Util/util"; @@ -11,13 +11,14 @@ import Widget, { WidgetData } from "Components/v2/widget"; import * as SentryLogger from "Util/sentry"; // The component uses the `match` prop supplied by withRouter for error logging. -interface Props extends RouteComponentProps { +interface Props extends PropsWithChildren { // Whether to show the fallback component when an error is caught. // If false, the component will render nothing on error. // Defaults to true. showFallbackOnError?: boolean; // Supplied by withLastFetchContext lastFetch: number | null; + match?: { params?: { id?: string } }; } interface State { @@ -75,7 +76,7 @@ class WidgetTreeErrorBoundary extends React.Component { }, credentials: "include", body: JSON.stringify({ - id: this.props.match.params.id, + id: this.props.match?.params?.id, stacktrace: errorInfo.componentStack, errorMessage: error.message, }), @@ -163,4 +164,19 @@ const WrappedWithLastFetch: React.ComponentType> = ( return ; }; +// https://reactrouter.com/en/main/start/faq#what-happened-to-withrouter-i-need-it +function withRouter( + Component: React.FunctionComponent, +) { + function ComponentWithRouterProp(props: ComponentProps) { + const location = useLocation(); + const navigate = useNavigate(); + const params = useParams(); + + return ; + } + + return ComponentWithRouterProp; +} + export default withRouter(WrappedWithLastFetch); diff --git a/assets/src/util/admin.tsx b/assets/src/util/admin.tsx index 63d5c6bfd..cfa785796 100644 --- a/assets/src/util/admin.tsx +++ b/assets/src/util/admin.tsx @@ -21,7 +21,7 @@ export type Screen = { const gatherSelectOptions = (rows, columnId) => { const options = rows.map((row) => row.values[columnId]); - const uniqueOptions = new Set(options); + const uniqueOptions = new Set(options); return Array.from(uniqueOptions); }; diff --git a/assets/tsconfig.json b/assets/tsconfig.json index 8b6156bd5..2ebed1dd0 100644 --- a/assets/tsconfig.json +++ b/assets/tsconfig.json @@ -3,7 +3,7 @@ "exclude": ["node_modules"], "compilerOptions": { /* Basic Options */ - "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */, + "target": "ES2018" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */, "module": "es2015" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, "lib": [ "dom",