From 22a9d566c9392dbb08bdb167582defba13ae845c Mon Sep 17 00:00:00 2001 From: Damian Stasik Date: Thu, 9 Dec 2021 23:40:32 +0100 Subject: [PATCH 01/18] refactor: upgrade React Router to v6 --- package-lock.json | 105 +++--------------- package.json | 5 +- .../Autocomplete/Autocomplete.react.js | 2 +- src/components/Chip/Chip.react.js | 2 +- src/components/FourOhFour/FourOhFour.react.js | 8 +- src/components/Toolbar/Toolbar.react.js | 10 +- src/dashboard/AppData.react.js | 5 +- src/dashboard/AppSelector.react.js | 10 +- src/dashboard/Apps/AppsIndex.react.js | 12 +- src/dashboard/Dashboard.js | 40 +++---- src/dashboard/Data/Browser/Browser.react.js | 15 +-- .../Data/Browser/CreateClassDialog.react.js | 8 +- .../Data/CloudCode/CloudCode.react.js | 8 +- src/dashboard/Data/Jobs/JobEdit.react.js | 5 +- src/dashboard/Data/Jobs/Jobs.react.js | 7 +- .../Push/PushAudiencesIndex.react.js | 5 +- src/dashboard/Push/PushDetails.react.js | 5 +- src/dashboard/Push/PushIndex.react.js | 10 +- src/dashboard/Push/PushNew.react.js | 5 +- .../Settings/GeneralSettings.react.js | 15 ++- src/dashboard/history.js | 6 +- src/lib/withRouter.js | 16 +++ src/parse-interface-guide/PIG.react.js | 11 +- src/parse-interface-guide/routes.js | 16 +-- 24 files changed, 146 insertions(+), 185 deletions(-) create mode 100644 src/lib/withRouter.js diff --git a/package-lock.json b/package-lock.json index 204dabd891..8c7b8c31d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4239,7 +4239,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -5056,8 +5055,7 @@ "buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "bytes": { "version": "3.1.0", @@ -5412,7 +5410,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" }, @@ -5420,8 +5417,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" } } }, @@ -8512,16 +8508,11 @@ "dev": true }, "history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.1.0.tgz", + "integrity": "sha512-zPuQgPacm2vH2xdORvGGz1wQMuHSIB56yNAy5FnLuwOwgSYyPKptJtcMm6Ev+hRGeS+GzhbmRacHzvlESbFwDg==", "requires": { - "@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" + "@babel/runtime": "^7.7.6" } }, "hoist-non-react-statics": { @@ -11706,15 +11697,6 @@ "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true }, - "mini-create-react-context": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", - "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", - "requires": { - "@babel/runtime": "^7.12.1", - "tiny-warning": "^1.0.3" - } - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -14765,12 +14747,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "path-to-regexp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.2.0.tgz", - "integrity": "sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA==", - "dev": true - }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -15589,49 +15565,20 @@ } }, "react-router": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.1.tgz", - "integrity": "sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ==", - "requires": { - "@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" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "requires": { - "isarray": "0.0.1" - } - } + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.0.2.tgz", + "integrity": "sha512-8/Wm3Ed8t7TuedXjAvV39+c8j0vwrI5qVsYqjFr5WkJjsJpEvNSoLRUbtqSEYzqaTUj1IV+sbPJxvO+accvU0Q==", + "requires": { + "history": "^5.1.0" } }, "react-router-dom": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.0.tgz", - "integrity": "sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.0.2.tgz", + "integrity": "sha512-cOpJ4B6raFutr0EG8O/M2fEoyQmwvZWomf1c6W2YXBZuFBx8oTk/zqjXghwScyhfrtnt0lANXV2182NQblRxFA==", "requires": { - "@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" + "history": "^5.1.0", + "react-router": "6.0.2" } }, "react-side-effect": { @@ -16087,11 +16034,6 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" }, - "resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -17816,16 +17758,6 @@ "readable-stream": "3" } }, - "tiny-invariant": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", - "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" - }, - "tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -18311,11 +18243,6 @@ "spdx-expression-parse": "^3.0.0" } }, - "value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, "value-or-promise": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/value-or-promise/-/value-or-promise-1.0.11.tgz", diff --git a/package.json b/package.json index c2c081e56e..015bf007b3 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,6 @@ "express": "4.17.1", "graphiql": "1.5.1", "graphql": "16.0.0", - "history": "4.10.1", "immutable": "4.0.0", "immutable-devtools": "0.1.5", "inquirer": "8.2.0", @@ -68,8 +67,7 @@ "react-json-view": "1.21.3", "react-popper-tooltip": "4.3.1", "react-redux": "5.1.2", - "react-router": "5.2.1", - "react-router-dom": "5.3.0", + "react-router-dom": "^6.0.2", "regenerator-runtime": "0.13.8", "semver": "7.3.4", "typescript": "4.4.4" @@ -104,7 +102,6 @@ "marked": "0.8.2", "node-sass": "6.0.1", "null-loader": "4.0.1", - "path-to-regexp": "3.2.0", "puppeteer": "3.0.0", "react-test-renderer": "16.13.1", "request": "2.88.2", diff --git a/src/components/Autocomplete/Autocomplete.react.js b/src/components/Autocomplete/Autocomplete.react.js index ef9cb666fc..624ea150b0 100644 --- a/src/components/Autocomplete/Autocomplete.react.js +++ b/src/components/Autocomplete/Autocomplete.react.js @@ -6,7 +6,7 @@ * the root directory of this source tree. */ import Position from 'lib/Position'; -import PropTypes from 'prop-types' +import PropTypes from 'lib/PropTypes' import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import styles from 'components/Autocomplete/Autocomplete.scss'; diff --git a/src/components/Chip/Chip.react.js b/src/components/Chip/Chip.react.js index 678063337e..c737699cf9 100644 --- a/src/components/Chip/Chip.react.js +++ b/src/components/Chip/Chip.react.js @@ -7,7 +7,7 @@ */ import React from 'react'; import styles from 'components/Chip/Chip.scss'; -import PropTypes from 'prop-types' +import PropTypes from 'lib/PropTypes' import Icon from 'components/Icon/Icon.react' let Chip = ({ value, onClose }) => ( diff --git a/src/components/FourOhFour/FourOhFour.react.js b/src/components/FourOhFour/FourOhFour.react.js index 53aba06e1a..3241947062 100644 --- a/src/components/FourOhFour/FourOhFour.react.js +++ b/src/components/FourOhFour/FourOhFour.react.js @@ -5,13 +5,15 @@ * This source code is licensed under the license found in the LICENSE file in * the root directory of this source tree. */ -import history from 'dashboard/history'; import React from 'react'; import styles from 'components/FourOhFour/FourOhFour.scss'; +import { withRouter } from 'lib/withRouter'; const EMOJI_COUNT = 30; -export default class FourOhFour extends React.Component { +export default +@withRouter +class FourOhFour extends React.Component { constructor() { super(); @@ -51,7 +53,7 @@ export default class FourOhFour extends React.Component {
Oh no, we can't find that page!
- +
diff --git a/src/components/Toolbar/Toolbar.react.js b/src/components/Toolbar/Toolbar.react.js index b73378ff86..505c37021e 100644 --- a/src/components/Toolbar/Toolbar.react.js +++ b/src/components/Toolbar/Toolbar.react.js @@ -9,17 +9,17 @@ import PropTypes from 'lib/PropTypes'; import React from 'react'; import Icon from 'components/Icon/Icon.react'; import styles from 'components/Toolbar/Toolbar.scss'; -import history from 'dashboard/history'; - -const goBack = () => history.goBack(); +import { useNavigate, useNavigationType, NavigationType } from 'react-router-dom'; let Toolbar = (props) => { + const action = useNavigationType(); + const navigate = useNavigate(); let backButton; - if ((props.relation || (props.filters && props.filters.size)) && history.action !== 'POP') { + if ((props.relation || (props.filters && props.filters.size)) && action !== NavigationType.Pop) { backButton = ( navigate(-1)} > ; } return ( diff --git a/src/dashboard/AppSelector.react.js b/src/dashboard/AppSelector.react.js index 722cfdb6f8..be338ac071 100644 --- a/src/dashboard/AppSelector.react.js +++ b/src/dashboard/AppSelector.react.js @@ -8,13 +8,15 @@ import AppsManager from 'lib/AppsManager'; import Dropdown from 'components/Dropdown/Dropdown.react'; import Field from 'components/Field/Field.react'; -import history from 'dashboard/history'; import Label from 'components/Label/Label.react'; import Modal from 'components/Modal/Modal.react'; import Option from 'components/Dropdown/Option.react'; import React from 'react'; +import { withRouter } from 'lib/withRouter'; -export default class AppSelector extends React.Component { +export default +@withRouter +class AppSelector extends React.Component { constructor(props) { super(props); let apps = AppsManager.apps(); @@ -26,11 +28,11 @@ export default class AppSelector extends React.Component { handleConfirm() { let newPath = location.pathname.replace(/\/_(\/|$)/, '/' + this.state.slug + '/'); - history.push(newPath); + this.props.navigate(newPath); } handleCancel() { - history.push('/apps'); + this.props.navigate('/apps'); } render() { diff --git a/src/dashboard/Apps/AppsIndex.react.js b/src/dashboard/Apps/AppsIndex.react.js index eca859d94b..4324b932de 100644 --- a/src/dashboard/Apps/AppsIndex.react.js +++ b/src/dashboard/Apps/AppsIndex.react.js @@ -7,7 +7,6 @@ */ import AppsManager from 'lib/AppsManager'; import FlowFooter from 'components/FlowFooter/FlowFooter.react'; -import history from 'dashboard/history'; import html from 'lib/htmlString'; import Icon from 'components/Icon/Icon.react'; import joinWithFinal from 'lib/joinWithFinal'; @@ -17,6 +16,8 @@ import React from 'react'; import styles from 'dashboard/Apps/AppsIndex.scss'; import baseStyles from 'stylesheets/base.scss'; import AppBadge from 'components/AppBadge/AppBadge.react'; +import { withRouter } from 'lib/withRouter'; +import { useNavigate } from 'react-router-dom'; function dash(value, content) { if (value === undefined) { @@ -64,7 +65,8 @@ let AppCard = ({ app, icon, }) => { - let canBrowse = app.serverInfo.error ? null : () => history.push(html`/apps/${app.slug}/browser`); + const navigate = useNavigate(); + let canBrowse = app.serverInfo.error ? null : () => navigate(html`/apps/${app.slug}/browser`); let versionMessage = app.serverInfo.error ?
Server not reachable: {app.serverInfo.error.toString()}
:
@@ -88,7 +90,9 @@ let AppCard = ({ } -export default class AppsIndex extends React.Component { +export default +@withRouter +class AppsIndex extends React.Component { constructor() { super(); this.state = { search: '' }; @@ -99,7 +103,7 @@ export default class AppsIndex extends React.Component { componentWillMount() { if (AppsManager.apps().length === 1) { const [app] = AppsManager.apps(); - history.push(`/apps/${app.slug}/browser`); + this.props.navigate(`/apps/${app.slug}/browser`); return; } document.body.addEventListener('keydown', this.focusField); diff --git a/src/dashboard/Dashboard.js b/src/dashboard/Dashboard.js index ebde1004f4..0a16ec8156 100644 --- a/src/dashboard/Dashboard.js +++ b/src/dashboard/Dashboard.js @@ -19,7 +19,6 @@ import Explorer from './Analytics/Explorer/Explorer.react'; import FourOhFour from 'components/FourOhFour/FourOhFour.react'; import GeneralSettings from './Settings/GeneralSettings.react'; import GraphQLConsole from './Data/ApiConsole/GraphQLConsole.react'; -import history from 'dashboard/history'; import HostingSettings from './Settings/HostingSettings.react'; import Icon from 'components/Icon/Icon.react'; import JobEdit from 'dashboard/Data/Jobs/JobEdit.react'; @@ -49,11 +48,7 @@ import { AsyncStatus } from 'lib/Constants'; import baseStyles from 'stylesheets/base.scss'; import { get } from 'lib/AJAX'; import { setBasePath } from 'lib/AJAX'; -import { - Router, - Switch, -} from 'react-router'; -import { Route, Redirect } from 'react-router-dom'; +import { BrowserRouter, Routes, Route, Redirect } from 'react-router-dom'; import { Helmet } from 'react-helmet'; import Playground from './Data/Playground/Playground.react'; @@ -204,18 +199,18 @@ export default class Dashboard extends React.Component { const SettingsRoute = ({ match }) => ( - + - + ) const JobsRoute = (props) => ( - + ( @@ -231,19 +226,20 @@ export default class Dashboard extends React.Component { )} /> + } /> - + ) const AnalyticsRoute = ({ match }) => ( - + - + ); const BrowserRoute = (props) => { @@ -254,7 +250,7 @@ export default class Dashboard extends React.Component { } const ApiConsoleRoute = (props) => ( - + ( @@ -271,12 +267,12 @@ export default class Dashboard extends React.Component { )} /> - + ) const AppRoute = ({ match }) => ( - + @@ -314,34 +310,34 @@ export default class Dashboard extends React.Component { - + ) const Index = () => (
- + - +
) return ( - +
Parse Dashboard - + - +
-
+ ); } } diff --git a/src/dashboard/Data/Browser/Browser.react.js b/src/dashboard/Data/Browser/Browser.react.js index 2b4d9beb11..3196b209d5 100644 --- a/src/dashboard/Data/Browser/Browser.react.js +++ b/src/dashboard/Data/Browser/Browser.react.js @@ -21,7 +21,6 @@ import AttachSelectedRowsDialog from 'dashboard/Data/Browser/AttachSel import CloneSelectedRowsDialog from 'dashboard/Data/Browser/CloneSelectedRowsDialog.react'; import EditRowDialog from 'dashboard/Data/Browser/EditRowDialog.react'; import ExportSelectedRowsDialog from 'dashboard/Data/Browser/ExportSelectedRowsDialog.react'; -import history from 'dashboard/history'; import { List, Map } from 'immutable'; import Notification from 'dashboard/Data/Browser/Notification.react'; import Parse from 'parse'; @@ -37,12 +36,14 @@ import subscribeTo from 'lib/subscribeTo'; import * as ColumnPreferences from 'lib/ColumnPreferences'; import { Helmet } from 'react-helmet'; import generatePath from 'lib/generatePath'; +import { withRouter } from 'lib/withRouter'; // The initial and max amount of rows fetched by lazy loading const MAX_ROWS_FETCHED = 200; export default @subscribeTo('Schema', 'schema') +@withRouter class Browser extends DashboardView { constructor() { super(); @@ -237,7 +238,7 @@ class Browser extends DashboardView { } return a.toUpperCase() < b.toUpperCase() ? -1 : 1; }); - history.replace(generatePath(this.context, 'browser/' + classes[0])); + this.props.navigate(generatePath(this.context, 'browser/' + classes[0]), { replace: true }); } } @@ -290,7 +291,7 @@ class Browser extends DashboardView { createClass(className) { this.props.schema.dispatch(ActionTypes.CREATE_CLASS, { className }).then(() => { this.state.counts[className] = 0; - history.push(generatePath(this.context, 'browser/' + className)); + this.props.navigate(generatePath(this.context, 'browser/' + className)); }).finally(() => { this.setState({ showCreateClassDialog: false }); }); @@ -300,7 +301,7 @@ class Browser extends DashboardView { this.props.schema.dispatch(ActionTypes.DROP_CLASS, { className }).then(() => { this.setState({showDropClassDialog: false }); delete this.state.counts[className]; - history.push(generatePath(this.context, 'browser')); + this.props.navigate(generatePath(this.context, 'browser')); }, (error) => { let msg = typeof error === 'string' ? error : error.message; if (msg) { @@ -793,7 +794,7 @@ class Browser extends DashboardView { const _filters = JSON.stringify(filters.toJSON()); const url = `browser/${source}${(filters.size === 0 ? '' : `?filters=${(encodeURIComponent(_filters))}`)}`; // filters param change is making the fetch call - history.push(generatePath(this.context, url)); + this.props.navigate(generatePath(this.context, url)); } } @@ -828,7 +829,7 @@ class Browser extends DashboardView { filterQueryString = encodeURIComponent(JSON.stringify(filters.toJSON())); } const url = `${this.getRelationURL()}${filterQueryString ? `?filters=${filterQueryString}` : ''}`; - history.push(url); + this.props.navigate(url); }); } @@ -838,7 +839,7 @@ class Browser extends DashboardView { constraint: 'eq', compareTo: id }]); - history.push(generatePath(this.context, `browser/${className}?filters=${encodeURIComponent(filters)}`)); + this.props.navigate(generatePath(this.context, `browser/${className}?filters=${encodeURIComponent(filters)}`)); } handlePointerCmdClick({ className, id, field = 'objectId' }) { diff --git a/src/dashboard/Data/Browser/CreateClassDialog.react.js b/src/dashboard/Data/Browser/CreateClassDialog.react.js index 49256390be..4adf2fe360 100644 --- a/src/dashboard/Data/Browser/CreateClassDialog.react.js +++ b/src/dashboard/Data/Browser/CreateClassDialog.react.js @@ -13,13 +13,15 @@ import Option from 'components/Dropdown/Option.react'; import React from 'react'; import { SpecialClasses } from 'lib/Constants'; import TextInput from 'components/TextInput/TextInput.react'; -import history from 'dashboard/history'; +import { withRouter } from 'lib/withRouter'; function validClassName(name) { return !!name.match(/^[a-zA-Z][_a-zA-Z0-9]*$/); } -export default class CreateClassDialog extends React.Component { +export default +@withRouter +class CreateClassDialog extends React.Component { constructor() { super(); this.state = { @@ -76,7 +78,7 @@ export default class CreateClassDialog extends React.Component { let type = this.state.type; let className = type === 'Custom' ? this.state.name : '_' + type; await this.props.onConfirm(className); - history.push(`/apps/${this.props.currentAppSlug}/browser/${className}`); + this.props.navigate(`/apps/${this.props.currentAppSlug}/browser/${className}`); this.props.onAddColumn(); }} onConfirm={() => { diff --git a/src/dashboard/Data/CloudCode/CloudCode.react.js b/src/dashboard/Data/CloudCode/CloudCode.react.js index e75324db7f..5fcb7f0154 100644 --- a/src/dashboard/Data/CloudCode/CloudCode.react.js +++ b/src/dashboard/Data/CloudCode/CloudCode.react.js @@ -9,17 +9,19 @@ import CodeSnippet from 'components/CodeSnippet/CodeSnippet.react'; import DashboardView from 'dashboard/DashboardView.react'; import EmptyState from 'components/EmptyState/EmptyState.react'; import FileTree from 'components/FileTree/FileTree.react'; -import history from 'dashboard/history'; import React from 'react'; import styles from 'dashboard/Data/CloudCode/CloudCode.scss'; import Toolbar from 'components/Toolbar/Toolbar.react'; import generatePath from 'lib/generatePath'; +import { withRouter } from 'lib/withRouter'; function getPath(params) { return params.splat; } -export default class CloudCode extends DashboardView { +export default +@withRouter +class CloudCode extends DashboardView { constructor() { super(); this.section = 'Core'; @@ -53,7 +55,7 @@ export default class CloudCode extends DashboardView { if (!fileName || release.files[fileName] === undefined) { // Means we're still in /cloud_code/. Let's redirect to /cloud_code/main.js - history.replace(generatePath(this.context, 'cloud_code/main.js')) + this.props.navigate(generatePath(this.context, 'cloud_code/main.js'), { replace: true }); } else { // Means we can load /cloud_code/ app.getSource(fileName).then( diff --git a/src/dashboard/Data/Jobs/JobEdit.react.js b/src/dashboard/Data/Jobs/JobEdit.react.js index 1c7008156c..6e1111ffe4 100644 --- a/src/dashboard/Data/Jobs/JobEdit.react.js +++ b/src/dashboard/Data/Jobs/JobEdit.react.js @@ -6,14 +6,15 @@ * the root directory of this source tree. */ import { ActionTypes } from 'lib/stores/JobsStore'; -import history from 'dashboard/history'; import JobsForm from 'dashboard/Data/Jobs/JobsForm.react'; import React from 'react'; import subscribeTo from 'lib/subscribeTo'; import generatePath from 'lib/generatePath'; import { CurrentApp } from 'context/currentApp'; +import { withRouter } from 'lib/withRouter'; @subscribeTo('Jobs', 'jobs') +@withRouter class JobEdit extends React.Component { static contextType = CurrentApp; @@ -51,7 +52,7 @@ class JobEdit extends React.Component { let promise = this.props.params.jobId ? this.props.jobs.dispatch(ActionTypes.EDIT, { jobId: this.props.params.jobId, updates: schedule }) : this.props.jobs.dispatch(ActionTypes.CREATE, { schedule }); - promise.then(() => {history.push(generatePath(this.context, 'jobs/scheduled'))}); + promise.then(() => {this.props.navigate(generatePath(this.context, 'jobs/scheduled'))}); return promise; } diff --git a/src/dashboard/Data/Jobs/Jobs.react.js b/src/dashboard/Data/Jobs/Jobs.react.js index 98ef7574fa..9a16aac6fe 100644 --- a/src/dashboard/Data/Jobs/Jobs.react.js +++ b/src/dashboard/Data/Jobs/Jobs.react.js @@ -10,7 +10,6 @@ import Button from 'components/Button/Button.react'; import * as DateUtils from 'lib/DateUtils'; import CategoryList from 'components/CategoryList/CategoryList.react'; import EmptyState from 'components/EmptyState/EmptyState.react'; -import history from 'dashboard/history'; import Icon from 'components/Icon/Icon.react'; import JobScheduleReminder from 'dashboard/Data/Jobs/JobScheduleReminder.react'; import Modal from 'components/Modal/Modal.react'; @@ -26,6 +25,7 @@ import TableHeader from 'components/Table/TableHeader.react'; import TableView from 'dashboard/TableView.react'; import Toolbar from 'components/Toolbar/Toolbar.react'; import generatePath from 'lib/generatePath'; +import { withRouter } from 'lib/withRouter'; let subsections = { all: 'All Jobs', @@ -63,6 +63,7 @@ function scheduleString(data) { // TODO: create scrollable view component that handles lazy fetch container on scroll export default @subscribeTo('Jobs', 'jobs') +@withRouter class Jobs extends TableView { constructor() { super(); @@ -92,11 +93,11 @@ class Jobs extends TableView { } navigateToNew() { - history.push(generatePath(this.context, 'jobs/new')); + this.props.navigate(generatePath(this.context, 'jobs/new')); } navigateToJob(jobId) { - history.push(generatePath(this.context, `jobs/edit/${jobId}`)) + this.props.navigate(generatePath(this.context, `jobs/edit/${jobId}`)) } loadData() { diff --git a/src/dashboard/Push/PushAudiencesIndex.react.js b/src/dashboard/Push/PushAudiencesIndex.react.js index 9168f0ea69..2ca46b0a0b 100644 --- a/src/dashboard/Push/PushAudiencesIndex.react.js +++ b/src/dashboard/Push/PushAudiencesIndex.react.js @@ -12,7 +12,6 @@ import Button from 'components/Button/Button.react'; import DashboardView from 'dashboard/DashboardView.react'; import EmptyState from 'components/EmptyState/EmptyState.react'; import FormModal from 'components/FormModal/FormModal.react'; -import history from 'dashboard/history'; import LoaderContainer from 'components/LoaderContainer/LoaderContainer.react'; import Modal from 'components/Modal/Modal.react'; import PushAudienceDialog from 'components/PushAudienceDialog/PushAudienceDialog.react'; @@ -27,12 +26,14 @@ import Toolbar from 'components/Toolbar/Toolbar.react'; import { formatAudienceSchema } from 'lib/PushUtils'; import { List } from 'immutable'; import generatePath from 'lib/generatePath'; +import { withRouter } from 'lib/withRouter'; const XHR_KEY = 'PushAudiencesIndex'; export default @subscribeTo('Schema', 'schema') @subscribeTo('PushAudiences', 'pushaudiences') +@withRouter class PushAudiencesIndex extends DashboardView { constructor() { super(); @@ -111,7 +112,7 @@ class PushAudiencesIndex extends DashboardView { } handleSendPush(objectId) { - history.push(generatePath(this.context, `push/new?audienceId=${objectId}`)); + this.props.navigate(generatePath(this.context, `push/new?audienceId=${objectId}`)); } renderRow(audience) { diff --git a/src/dashboard/Push/PushDetails.react.js b/src/dashboard/Push/PushDetails.react.js index cc022301b7..58d992b6bc 100644 --- a/src/dashboard/Push/PushDetails.react.js +++ b/src/dashboard/Push/PushDetails.react.js @@ -15,7 +15,6 @@ import Field from 'components/Field/Field.react'; import Fieldset from 'components/Fieldset/Fieldset.react'; import FieldStyles from 'components/Field/Field.scss'; import FlowView from 'components/FlowView/FlowView.react'; -import history from 'dashboard/history'; import Label from 'components/Label/Label.react'; import LoaderContainer from 'components/LoaderContainer/LoaderContainer.react'; import Parse from 'parse'; @@ -33,6 +32,7 @@ import { Directions } from 'lib/Constants'; import { Link } from 'react-router-dom'; import { tableInfoBuilder } from 'lib/PushUtils'; import generatePath from 'lib/generatePath'; +import { withRouter } from 'lib/withRouter'; const EXP_STATS_URL = 'http://docs.parseplatform.org/ios/guide/#push-experiments'; @@ -202,6 +202,7 @@ const DROPDOWN_KEY_GROUP_B = 'Group B'; export default @subscribeTo('Schema', 'schema') +@withRouter class PushDetails extends DashboardView { constructor() { super(); @@ -586,7 +587,7 @@ class PushDetails extends DashboardView { if (error) { promise.reject({ error }); } else { - history.push(generatePath(this.context, 'push/activity')); + this.props.navigate(generatePath(this.context, 'push/activity')); } }, (error) => { promise.reject({ error }); diff --git a/src/dashboard/Push/PushIndex.react.js b/src/dashboard/Push/PushIndex.react.js index 5e025fb0b6..3a9c4645da 100644 --- a/src/dashboard/Push/PushIndex.react.js +++ b/src/dashboard/Push/PushIndex.react.js @@ -11,7 +11,6 @@ import Button from 'components/Button/Button.react'; import CategoryList from 'components/CategoryList/CategoryList.react'; import DashboardView from 'dashboard/DashboardView.react'; import EmptyState from 'components/EmptyState/EmptyState.react'; -import history from 'dashboard/history'; import LoaderContainer from 'components/LoaderContainer/LoaderContainer.react'; import LoaderDots from 'components/LoaderDots/LoaderDots.react'; import React from 'react'; @@ -22,6 +21,7 @@ import stylesTable from 'dashboard/TableView.scss'; import TableHeader from 'components/Table/TableHeader.react'; import Toolbar from 'components/Toolbar/Toolbar.react'; import generatePath from 'lib/generatePath'; +import { withRouter } from 'lib/withRouter'; const PUSH_TYPE_ALL = 'all'; const PUSH_TYPE_CAMPAIGN = 'campaign'; @@ -227,7 +227,9 @@ let getPushTime = (pushTime, updatedAt) => { return result; } -export default class PushIndex extends DashboardView { +export default +@withRouter +class PushIndex extends DashboardView { constructor() { super(); this.section = 'Push'; @@ -294,11 +296,11 @@ export default class PushIndex extends DashboardView { } navigateToNew() { - history.push(generatePath(this.context, 'push/new')); + this.props.navigate(generatePath(this.context, 'push/new')); } navigateToDetails(objectId) { - history.push(generatePath(this.context, `push/${objectId}`)); + this.props.navigate(generatePath(this.context, `push/${objectId}`)); } handleShowMore(page) { diff --git a/src/dashboard/Push/PushNew.react.js b/src/dashboard/Push/PushNew.react.js index 3c964a161c..612825975b 100644 --- a/src/dashboard/Push/PushNew.react.js +++ b/src/dashboard/Push/PushNew.react.js @@ -17,7 +17,6 @@ import Field from 'components/Field/Field.react'; import Fieldset from 'components/Fieldset/Fieldset.react'; import FieldStyles from 'components/Field/Field.scss'; import FlowView from 'components/FlowView/FlowView.react'; -import history from 'dashboard/history'; import joinWithFinal from 'lib/joinWithFinal'; import Label from 'components/Label/Label.react'; import Option from 'components/Dropdown/Option.react'; @@ -37,6 +36,7 @@ import Toolbar from 'components/Toolbar/Toolbar.react'; import { Directions } from 'lib/Constants'; import { extractExpiration, extractPushTime } from 'lib/extractTime'; import generatePath from 'lib/generatePath'; +import { withRouter } from 'lib/withRouter'; const PARSE_SERVER_SUPPORTS_AB_TESTING = false; @@ -124,6 +124,7 @@ const XHR_KEY = 'PushNew'; export default @subscribeTo('Schema', 'schema') @subscribeTo('PushAudiences', 'pushaudiences') +@withRouter class PushNew extends DashboardView { constructor() { super(); @@ -230,7 +231,7 @@ class PushNew extends DashboardView { //TODO: global success message banner for passing successful creation - store should also be cleared const PARSE_SERVER_SUPPORTS_PUSH_INDEX = false; if (PARSE_SERVER_SUPPORTS_PUSH_INDEX) { - history.push(generatePath(this.context, 'push/activity')); + this.props.navigate(generatePath(this.context, 'push/activity')); } else { return; } diff --git a/src/dashboard/Settings/GeneralSettings.react.js b/src/dashboard/Settings/GeneralSettings.react.js index 31de3b49b2..2c9eac9cba 100644 --- a/src/dashboard/Settings/GeneralSettings.react.js +++ b/src/dashboard/Settings/GeneralSettings.react.js @@ -18,7 +18,6 @@ import FormButton from 'components/FormButton/FormButton. import FormModal from 'components/FormModal/FormModal.react'; import FormNote from 'components/FormNote/FormNote.react'; import getSiteDomain from 'lib/getSiteDomain'; -import history from 'dashboard/history'; import joinWithFinal from 'lib/joinWithFinal'; import KeyField from 'components/KeyField/KeyField.react'; import Label from 'components/Label/Label.react'; @@ -37,7 +36,8 @@ import Toolbar from 'components/Toolbar/Toolbar.react' import unique from 'lib/unique'; import validateAndSubmitConnectionString from 'lib/validateAndSubmitConnectionString'; import styles from 'dashboard/Settings/GeneralSettings.scss'; -import { Link } from 'react-router-dom'; +import { Link, useNavigate } from 'react-router-dom'; +import { withRouter } from 'lib/withRouter'; const DEFAULT_SETTINGS_LABEL_WIDTH = 62; @@ -204,6 +204,7 @@ let ManageAppFields = ({ transferAppMessage, deleteApp, }) => { + const navigate = useNavigate(); let migrateAppField = null; if (!mongoURL && !hasInProgressMigration) { migrateAppField = } input={ history.push(`/apps/${appSlug}/migration`)} + onClick={() => navigate(`/apps/${appSlug}/migration`)} value='View progress' />} /> } else { migrateAppField = [); } -export default class GeneralSettings extends DashboardView { +export default +@withRouter +class GeneralSettings extends DashboardView { constructor() { super(); this.section = 'App Settings'; @@ -424,7 +427,7 @@ export default class GeneralSettings extends DashboardView { return promise; }} onClose={closeModalWithConnectionString} - onSuccess={() => history.push(`/apps/${this.context.slug}/migration`)} + onSuccess={() => this.props.navigate(`/apps/${this.context.slug}/migration`)} clearFields={() => this.setState({ migrationMongoURL: '', migrationWarnings: [], @@ -535,7 +538,7 @@ export default class GeneralSettings extends DashboardView { inProgressText={'Deleting\u2026'} enabled={this.state.password.length > 0} onSubmit={() => AppsManager.deleteApp(this.context.slug, this.state.password)} - onSuccess={() => history.push('/apps')} + onSuccess={() => this.props.navigate('/apps')} onClose={() => this.setState({showDeleteAppModal: false})} clearFields={() => this.setState({password: ''})}> {passwordField} diff --git a/src/dashboard/history.js b/src/dashboard/history.js index 35dd81d965..dd9ee841b3 100644 --- a/src/dashboard/history.js +++ b/src/dashboard/history.js @@ -6,7 +6,9 @@ * the root directory of this source tree. */ -import { createBrowserHistory } from 'history'; const path = window.PARSE_DASHBOARD_PATH || '/'; -export default createBrowserHistory({ basename: path }); +// createBrowserHistory({ basename: path }); + + export default {} + \ No newline at end of file diff --git a/src/lib/withRouter.js b/src/lib/withRouter.js new file mode 100644 index 0000000000..fcb1a84fb2 --- /dev/null +++ b/src/lib/withRouter.js @@ -0,0 +1,16 @@ +import React from 'react'; +import { useParams, useLocation } from 'react-router-dom'; + +export function withRouter(Component) { + function render(props) { + const params = useParams(); + const navigate = useLocation(); + + return ; + } + + const name = Component.displayName || Component.name; + render.displayName = `withRouter(${name})`; + + return render; +} diff --git a/src/parse-interface-guide/PIG.react.js b/src/parse-interface-guide/PIG.react.js index 15a009dc8a..766ec5955d 100644 --- a/src/parse-interface-guide/PIG.react.js +++ b/src/parse-interface-guide/PIG.react.js @@ -6,20 +6,23 @@ * the root directory of this source tree. */ import * as ComponentsMap from 'parse-interface-guide/ComponentsMap'; -import { Link } from 'react-router-dom'; +import { NavLink } from 'react-router-dom'; import Icon from 'components/Icon/Icon.react'; import PropsTable from 'parse-interface-guide/PropsTable.react'; import React from 'react'; import styles from 'parse-interface-guide/PIG.scss'; import beautify from 'js-beautify'; import CodeSnippet from 'components/CodeSnippet/CodeSnippet.react'; +import { withRouter } from 'lib/withRouter'; let PIGRow = ({ title, children }) =>
{title}
{children}
; -export default class PIG extends React.Component { +export default +@withRouter +class PIG extends React.Component { constructor() { super(); @@ -46,7 +49,7 @@ export default class PIG extends React.Component { }}/> {components.map((name) => { return name.toLowerCase().indexOf(this.state.query.toLowerCase()) !== -1 - ? {name} + ? isActive ? styles.active : undefined} key={name} to={`/${name}`}>{name} : null; })}
@@ -54,7 +57,7 @@ export default class PIG extends React.Component { } renderContent() { - let componentInfo = ComponentsMap[this.props.params.component]; + let componentInfo = ComponentsMap[this.props.params['*']]; if (!componentInfo) { componentInfo = ComponentsMap[Object.keys(ComponentsMap)[0]]; } diff --git a/src/parse-interface-guide/routes.js b/src/parse-interface-guide/routes.js index c270bb8f64..d6cc233d0a 100644 --- a/src/parse-interface-guide/routes.js +++ b/src/parse-interface-guide/routes.js @@ -7,18 +7,14 @@ */ import PIG from 'parse-interface-guide/PIG.react'; import React from 'react'; -import { Router, Route } from 'react-router'; -import { createBrowserHistory } from 'history'; -const history = createBrowserHistory({}); +import { BrowserRouter, Routes, Route } from 'react-router-dom'; const routes = ( - -
- { - return - }} /> -
-
+ + + } /> + + ); export default routes From eae041365a0922f5cb8cd2b92bdcb8e91ef00c01 Mon Sep 17 00:00:00 2001 From: Damian Stasik Date: Fri, 10 Dec 2021 00:14:10 +0100 Subject: [PATCH 02/18] Start refactoring the route list --- src/dashboard/AppData.react.js | 5 +- src/dashboard/Dashboard.js | 94 +++++++-------------- src/dashboard/Data/Browser/Browser.react.js | 1 + src/lib/withRouter.js | 4 +- 4 files changed, 37 insertions(+), 67 deletions(-) diff --git a/src/dashboard/AppData.react.js b/src/dashboard/AppData.react.js index a81dd96a7c..86fabc465b 100644 --- a/src/dashboard/AppData.react.js +++ b/src/dashboard/AppData.react.js @@ -10,6 +10,7 @@ import AppSelector from 'dashboard/AppSelector.react'; import AppsManager from 'lib/AppsManager'; import { CurrentApp } from 'context/currentApp'; import { withRouter } from 'lib/withRouter'; +import { Outlet } from 'react-router-dom'; @withRouter class AppData extends React.Component { @@ -27,9 +28,7 @@ class AppData extends React.Component { } return ( -
- {this.props.children} -
+
); } diff --git a/src/dashboard/Dashboard.js b/src/dashboard/Dashboard.js index 0a16ec8156..84ab3e09b4 100644 --- a/src/dashboard/Dashboard.js +++ b/src/dashboard/Dashboard.js @@ -48,7 +48,7 @@ import { AsyncStatus } from 'lib/Constants'; import baseStyles from 'stylesheets/base.scss'; import { get } from 'lib/AJAX'; import { setBasePath } from 'lib/AJAX'; -import { BrowserRouter, Routes, Route, Redirect } from 'react-router-dom'; +import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'; import { Helmet } from 'react-helmet'; import Playground from './Data/Playground/Playground.react'; @@ -226,15 +226,15 @@ export default class Dashboard extends React.Component { )} /> - } /> - + {/* } /> */} + {/* */} ) const AnalyticsRoute = ({ match }) => ( - + {/* */} @@ -266,63 +266,10 @@ export default class Dashboard extends React.Component { )} /> - + {/* */} ) - const AppRoute = ({ match }) => ( - - - - - - - - - - - - - ( - - )} /> - - - - - - - - - - - ( - - )} /> - - - ( - - )} /> - - {/* Unused routes... */} - - - - - - - ) - - const Index = () => ( -
- - - - - -
- ) return (
@@ -330,10 +277,33 @@ export default class Dashboard extends React.Component { Parse Dashboard - - - - + } /> + + + } /> + }> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + }/> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + + } /> + } />
diff --git a/src/dashboard/Data/Browser/Browser.react.js b/src/dashboard/Data/Browser/Browser.react.js index 3196b209d5..6c7437f683 100644 --- a/src/dashboard/Data/Browser/Browser.react.js +++ b/src/dashboard/Data/Browser/Browser.react.js @@ -148,6 +148,7 @@ class Browser extends DashboardView { this.saveEditCloneRow = this.saveEditCloneRow.bind(this); this.abortEditCloneRow = this.abortEditCloneRow.bind(this); this.cancelPendingEditRows = this.cancelPendingEditRows.bind(this); + this.redirectToFirstClass = this.redirectToFirstClass.bind(this); this.dataBrowserRef = React.createRef(); } diff --git a/src/lib/withRouter.js b/src/lib/withRouter.js index fcb1a84fb2..9ae1f709fd 100644 --- a/src/lib/withRouter.js +++ b/src/lib/withRouter.js @@ -1,10 +1,10 @@ import React from 'react'; -import { useParams, useLocation } from 'react-router-dom'; +import { useParams, useNavigate } from 'react-router-dom'; export function withRouter(Component) { function render(props) { const params = useParams(); - const navigate = useLocation(); + const navigate = useNavigate(); return ; } From 4348179c92a92df5694e887c03f0860f1ba1da31 Mon Sep 17 00:00:00 2001 From: Damian Stasik Date: Fri, 10 Dec 2021 00:15:07 +0100 Subject: [PATCH 03/18] Get rid of another unnecessary div wrapper --- src/dashboard/Dashboard.js | 62 ++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/src/dashboard/Dashboard.js b/src/dashboard/Dashboard.js index 84ab3e09b4..2cb17785df 100644 --- a/src/dashboard/Dashboard.js +++ b/src/dashboard/Dashboard.js @@ -272,41 +272,39 @@ export default class Dashboard extends React.Component { return ( -
- - Parse Dashboard - - - } /> + + Parse Dashboard + + + } /> - - } /> - }> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - }/> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - + + } /> + }> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + }/> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + - } /> - } /> - - -
+ } /> + } /> + +
); } From eb4f593131eb5e64fe9344509f25127fd6a27b85 Mon Sep 17 00:00:00 2001 From: Damian Stasik Date: Sat, 22 Jan 2022 21:47:49 +0100 Subject: [PATCH 04/18] Update router to latest version --- package-lock.json | 24 ++++++++++++------------ package.json | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0cad50ac70..25150656a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8571,9 +8571,9 @@ "dev": true }, "history": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/history/-/history-5.1.0.tgz", - "integrity": "sha512-zPuQgPacm2vH2xdORvGGz1wQMuHSIB56yNAy5FnLuwOwgSYyPKptJtcMm6Ev+hRGeS+GzhbmRacHzvlESbFwDg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.2.0.tgz", + "integrity": "sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==", "requires": { "@babel/runtime": "^7.7.6" } @@ -15667,20 +15667,20 @@ } }, "react-router": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.0.2.tgz", - "integrity": "sha512-8/Wm3Ed8t7TuedXjAvV39+c8j0vwrI5qVsYqjFr5WkJjsJpEvNSoLRUbtqSEYzqaTUj1IV+sbPJxvO+accvU0Q==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz", + "integrity": "sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==", "requires": { - "history": "^5.1.0" + "history": "^5.2.0" } }, "react-router-dom": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.0.2.tgz", - "integrity": "sha512-cOpJ4B6raFutr0EG8O/M2fEoyQmwvZWomf1c6W2YXBZuFBx8oTk/zqjXghwScyhfrtnt0lANXV2182NQblRxFA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz", + "integrity": "sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==", "requires": { - "history": "^5.1.0", - "react-router": "6.0.2" + "history": "^5.2.0", + "react-router": "6.2.1" } }, "react-side-effect": { diff --git a/package.json b/package.json index a95a0ea7e2..4c069843c3 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "react-json-view": "1.21.3", "react-popper-tooltip": "4.3.1", "react-redux": "5.1.2", - "react-router-dom": "^6.0.2", + "react-router-dom": "^6.2.1", "regenerator-runtime": "0.13.8", "semver": "7.3.4", "typescript": "4.5.4" From 59584f9cee8c1a8845f380b63819256c357f662f Mon Sep 17 00:00:00 2001 From: Damian Stasik Date: Sat, 22 Jan 2022 21:51:00 +0100 Subject: [PATCH 05/18] Refactor AppData into functional component --- src/dashboard/AppData.react.js | 45 ++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/src/dashboard/AppData.react.js b/src/dashboard/AppData.react.js index 86fabc465b..de33aa0703 100644 --- a/src/dashboard/AppData.react.js +++ b/src/dashboard/AppData.react.js @@ -9,29 +9,32 @@ import React from 'react'; import AppSelector from 'dashboard/AppSelector.react'; import AppsManager from 'lib/AppsManager'; import { CurrentApp } from 'context/currentApp'; -import { withRouter } from 'lib/withRouter'; -import { Outlet } from 'react-router-dom'; +import { Outlet, useNavigate , useParams} from 'react-router-dom'; -@withRouter -class AppData extends React.Component { - render() { - if (this.props.params.appId === '_') { - return ; - } - //Find by name to catch edge cases around escaping apostrophes in URLs - let current = AppsManager.findAppBySlugOrName(this.props.params.appId); - if (current) { - current.setParseKeys(); - } else { - this.props.navigate('/apps', { replate: true }); - return
; - } - return ( - - - - ); + +function AppData() { + const navigate = useNavigate(); + const params = useParams(); + + if (params.appId === '_') { + return ; + } + + // Find by name to catch edge cases around escaping apostrophes in URLs + let current = AppsManager.findAppBySlugOrName(params.appId); + + if (current) { + current.setParseKeys(); + } else { + navigate('/apps', { replace: true }); + return
; } + + return ( + + + + ); } export default AppData; From 352fe63fde078b75d3351835931d0101fe36c942 Mon Sep 17 00:00:00 2001 From: Damian Stasik Date: Sat, 22 Jan 2022 23:03:30 +0100 Subject: [PATCH 06/18] Convert all of the routes to the new convention --- src/dashboard/Dashboard.js | 140 ++++++++---------- .../Data/ApiConsole/ApiConsole.react.js | 13 +- src/dashboard/Data/Jobs/JobsData.react.js | 18 +-- src/dashboard/Data/Logs/Logs.react.js | 5 +- src/dashboard/Settings/SettingsData.react.js | 16 +- src/lib/withRouter.js | 6 +- 6 files changed, 91 insertions(+), 107 deletions(-) diff --git a/src/dashboard/Dashboard.js b/src/dashboard/Dashboard.js index 2cb17785df..1003ada011 100644 --- a/src/dashboard/Dashboard.js +++ b/src/dashboard/Dashboard.js @@ -197,78 +197,7 @@ export default class Dashboard extends React.Component { ); - const SettingsRoute = ({ match }) => ( - - - - - - - - - - ) - - const JobsRoute = (props) => ( - - ( - - - - )} /> - ( - - - - )} /> - ( - - - - )} /> - {/* } /> */} - {/* */} - - ) - - const AnalyticsRoute = ({ match }) => ( - - - {/* */} - - - - - - ); - - const BrowserRoute = (props) => { - if (ShowSchemaOverview) { - return - } - return - } - - const ApiConsoleRoute = (props) => ( - - ( - - - - )} /> - ( - - - - )} /> - ( - - - - )} /> - {/* */} - - ) + const BrowserRoute = () => ShowSchemaOverview ? : ; return ( @@ -280,30 +209,77 @@ export default class Dashboard extends React.Component { } /> + }> - } /> + } /> + } /> - } /> - } /> - } /> + + } /> + } /> + } /> + } /> } /> } /> - }/> + + }> + } /> + } /> + } /> + + } /> + + } /> + } /> + } /> - } /> + + }> + } /> + } /> + } /> + } /> + + } /> + + } /> + } /> + } /> } /> } /> - } /> + } /> + + {/* Unused routes... */} + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + + }> + } /> + } /> + } /> + } /> + } /> + } /> + + - } /> - } /> - + } /> + } /> + + } /> ); diff --git a/src/dashboard/Data/ApiConsole/ApiConsole.react.js b/src/dashboard/Data/ApiConsole/ApiConsole.react.js index 46ab64cef9..dd11396839 100644 --- a/src/dashboard/Data/ApiConsole/ApiConsole.react.js +++ b/src/dashboard/Data/ApiConsole/ApiConsole.react.js @@ -8,8 +8,12 @@ import React from 'react'; import CategoryList from 'components/CategoryList/CategoryList.react'; import DashboardView from 'dashboard/DashboardView.react'; +import { Outlet } from 'react-router-dom'; +import { withRouter } from 'lib/withRouter'; -export default class ApiConsole extends DashboardView { +export default +@withRouter +class ApiConsole extends DashboardView { constructor() { super(); this.section = 'Core'; @@ -17,8 +21,8 @@ export default class ApiConsole extends DashboardView { } renderSidebar() { - const { path } = this.props.match; - const current = path.substr(path.lastIndexOf('/') + 1, path.length - 1); + const { pathname } = this.props.location; + const current = pathname.substr(pathname.lastIndexOf('/') + 1, pathname.length - 1); return ( ; } } diff --git a/src/dashboard/Data/Jobs/JobsData.react.js b/src/dashboard/Data/Jobs/JobsData.react.js index 574ba5453c..441dd7c25b 100644 --- a/src/dashboard/Data/Jobs/JobsData.react.js +++ b/src/dashboard/Data/Jobs/JobsData.react.js @@ -7,6 +7,7 @@ */ import React from 'react'; import { CurrentApp } from 'context/currentApp'; +import { Outlet } from 'react-router-dom'; export default class JobsData extends React.Component { static contextType = CurrentApp; @@ -58,15 +59,14 @@ export default class JobsData extends React.Component { } render() { - let child = React.Children.only(this.props.children); - return React.cloneElement( - child, - { - ...child.props, - availableJobs: this.state.jobs, - jobsInUse: this.state.inUse, - release: this.state.release - } + return ( + ); } } diff --git a/src/dashboard/Data/Logs/Logs.react.js b/src/dashboard/Data/Logs/Logs.react.js index 2e2a5c5027..9b59059b83 100644 --- a/src/dashboard/Data/Logs/Logs.react.js +++ b/src/dashboard/Data/Logs/Logs.react.js @@ -15,13 +15,16 @@ import ReleaseInfo from 'components/ReleaseInfo/ReleaseInfo'; import Toolbar from 'components/Toolbar/Toolbar.react'; import styles from 'dashboard/Data/Logs/Logs.scss'; +import { withRouter } from 'lib/withRouter'; let subsections = { info: 'Info', error: 'Error' }; -export default class Logs extends DashboardView { +export default +@withRouter +class Logs extends DashboardView { constructor() { super(); this.section = 'Core'; diff --git a/src/dashboard/Settings/SettingsData.react.js b/src/dashboard/Settings/SettingsData.react.js index 4b2a37e931..161ea0614b 100644 --- a/src/dashboard/Settings/SettingsData.react.js +++ b/src/dashboard/Settings/SettingsData.react.js @@ -7,6 +7,7 @@ */ import React from 'react'; import { CurrentApp } from 'context/currentApp'; +import { Outlet } from 'react-router-dom'; export default class SettingsData extends React.Component { static contextType = CurrentApp; @@ -43,14 +44,13 @@ export default class SettingsData extends React.Component { } render() { - let child = React.Children.only(this.props.children); - return React.cloneElement( - child, - { - ...child.props, - initialFields: this.state.fields, - saveChanges: this.saveChanges.bind(this) - } + return ( + ); } } diff --git a/src/lib/withRouter.js b/src/lib/withRouter.js index 9ae1f709fd..898e0f6cd3 100644 --- a/src/lib/withRouter.js +++ b/src/lib/withRouter.js @@ -1,12 +1,14 @@ import React from 'react'; -import { useParams, useNavigate } from 'react-router-dom'; +import { useParams, useNavigate, useOutletContext, useLocation } from 'react-router-dom'; export function withRouter(Component) { function render(props) { const params = useParams(); const navigate = useNavigate(); + const outletContext = useOutletContext(); + const location = useLocation(); - return ; + return ; } const name = Component.displayName || Component.name; From 04373fa9691d8bcb8dfe41e80990eb0ebc121766 Mon Sep 17 00:00:00 2001 From: Damian Stasik Date: Sat, 22 Jan 2022 23:10:58 +0100 Subject: [PATCH 07/18] Remote unused file --- src/dashboard/history.js | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 src/dashboard/history.js diff --git a/src/dashboard/history.js b/src/dashboard/history.js deleted file mode 100644 index dd9ee841b3..0000000000 --- a/src/dashboard/history.js +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2016-present, Parse, LLC - * All rights reserved. - * - * This source code is licensed under the license found in the LICENSE file in - * the root directory of this source tree. - */ - - -const path = window.PARSE_DASHBOARD_PATH || '/'; -// createBrowserHistory({ basename: path }); - - export default {} - \ No newline at end of file From 6bfef3da7735d22cdb3dad362216a554bdc1d74a Mon Sep 17 00:00:00 2001 From: Damian Stasik Date: Sat, 22 Jan 2022 23:11:26 +0100 Subject: [PATCH 08/18] Wrap Explorer with router HOC --- src/dashboard/Analytics/Explorer/Explorer.react.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dashboard/Analytics/Explorer/Explorer.react.js b/src/dashboard/Analytics/Explorer/Explorer.react.js index 4134412ff3..56b7405719 100644 --- a/src/dashboard/Analytics/Explorer/Explorer.react.js +++ b/src/dashboard/Analytics/Explorer/Explorer.react.js @@ -28,6 +28,7 @@ import stylesTable from 'components/Table/Table.scss'; import subscribeTo from 'lib/subscribeTo'; import Toolbar from 'components/Toolbar/Toolbar.react'; import baseStyles from 'stylesheets/base.scss'; +import { withRouter } from 'lib/withRouter'; let buildFriendlyName = (query) => { let name = [query.source]; @@ -40,6 +41,7 @@ let buildFriendlyName = (query) => { export default @subscribeTo('AnalyticsQuery', 'customQueries') +@withRouter class Explorer extends DashboardView { constructor() { super(); From 44458b99c94d789072e1038d9b608faa90449974 Mon Sep 17 00:00:00 2001 From: Damian Stasik Date: Sun, 8 May 2022 22:09:36 +0200 Subject: [PATCH 09/18] Update react-router-dom --- package-lock.json | 20 ++++++++++---------- package.json | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index dd7288ec42..485f8bc408 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8571,9 +8571,9 @@ "dev": true }, "history": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/history/-/history-5.2.0.tgz", - "integrity": "sha512-uPSF6lAJb3nSePJ43hN3eKj1dTWpN9gMod0ZssbFTIsen+WehTmEadgL+kg78xLJFdRfrrC//SavDzmRVdE+Ig==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", + "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", "requires": { "@babel/runtime": "^7.7.6" } @@ -15670,20 +15670,20 @@ } }, "react-router": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.1.tgz", - "integrity": "sha512-2fG0udBtxou9lXtK97eJeET2ki5//UWfQSl1rlJ7quwe6jrktK9FCCc8dQb5QY6jAv3jua8bBQRhhDOM/kVRsg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz", + "integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==", "requires": { "history": "^5.2.0" } }, "react-router-dom": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.1.tgz", - "integrity": "sha512-I6Zax+/TH/cZMDpj3/4Fl2eaNdcvoxxHoH1tYOREsQ22OKDYofGebrNm6CTPUcvLvZm63NL/vzCYdjf9CUhqmA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz", + "integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==", "requires": { "history": "^5.2.0", - "react-router": "6.2.1" + "react-router": "6.3.0" } }, "react-side-effect": { diff --git a/package.json b/package.json index dbc17f785e..ae225f9f29 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "react-json-view": "1.21.3", "react-popper-tooltip": "4.3.1", "react-redux": "5.1.2", - "react-router-dom": "^6.2.1", + "react-router-dom": "^6.3.0", "regenerator-runtime": "0.13.8", "semver": "7.3.4", "typescript": "4.5.4" From dd05ba54851109ce4a0eb64885b1090701cb8b4c Mon Sep 17 00:00:00 2001 From: Damian Stasik <920747+damianstasik@users.noreply.github.com> Date: Sun, 25 Sep 2022 13:31:52 +0200 Subject: [PATCH 10/18] Update router to 6.4 --- package-lock.json | 31 ++++++++++++++----------------- package.json | 2 +- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40f0301adf..2778f88a10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3197,6 +3197,11 @@ "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz", "integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==" }, + "@remix-run/router": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.0.1.tgz", + "integrity": "sha512-eBV5rvW4dRFOU1eajN7FmYxjAIVz/mRHgUE9En9mBn6m3mulK3WTR5C3iQhL9MZ14rWAq+xOlEaCkDiW0/heOg==" + }, "@saithodev/semantic-release-backmerge": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@saithodev/semantic-release-backmerge/-/semantic-release-backmerge-2.1.2.tgz", @@ -8388,14 +8393,6 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, - "history": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", - "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", - "requires": { - "@babel/runtime": "^7.7.6" - } - }, "hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -15655,20 +15652,20 @@ } }, "react-router": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz", - "integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.4.1.tgz", + "integrity": "sha512-OJASKp5AykDWFewgWUim1vlLr7yfD4vO/h+bSgcP/ix8Md+LMHuAjovA74MQfsfhQJGGN1nHRhwS5qQQbbBt3A==", "requires": { - "history": "^5.2.0" + "@remix-run/router": "1.0.1" } }, "react-router-dom": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz", - "integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.4.1.tgz", + "integrity": "sha512-MY7NJCrGNVJtGp8ODMOBHu20UaIkmwD2V3YsAOUQoCXFk7Ppdwf55RdcGyrSj+ycSL9Uiwrb3gTLYSnzcRoXww==", "requires": { - "history": "^5.2.0", - "react-router": "6.3.0" + "@remix-run/router": "1.0.1", + "react-router": "6.4.1" } }, "react-side-effect": { diff --git a/package.json b/package.json index 097aea675e..084a256d03 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "react-json-view": "1.21.3", "react-popper-tooltip": "4.4.2", "react-redux": "8.0.2", - "react-router-dom": "6.3.0", + "react-router-dom": "6.4.1", "regenerator-runtime": "0.13.9", "semver": "7.3.7", "typescript": "4.7.4" From f69d4c18dd1ad2de0488914aeb674be992815526 Mon Sep 17 00:00:00 2001 From: Damian Stasik <920747+damianstasik@users.noreply.github.com> Date: Sun, 25 Sep 2022 14:41:00 +0200 Subject: [PATCH 11/18] Pass basename if available --- src/dashboard/Dashboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dashboard/Dashboard.js b/src/dashboard/Dashboard.js index 1003ada011..7707fed6e1 100644 --- a/src/dashboard/Dashboard.js +++ b/src/dashboard/Dashboard.js @@ -200,7 +200,7 @@ export default class Dashboard extends React.Component { const BrowserRoute = () => ShowSchemaOverview ? : ; return ( - + Parse Dashboard From a0ebac017a68138a016b6be703c7376c41c0eebd Mon Sep 17 00:00:00 2001 From: Damian Stasik <920747+damianstasik@users.noreply.github.com> Date: Sun, 25 Sep 2022 16:50:26 +0200 Subject: [PATCH 12/18] Separate exports from decorated classes to make code a bit more clearer --- src/components/FourOhFour/FourOhFour.react.js | 3 ++- src/dashboard/Analytics/Explorer/Explorer.react.js | 3 ++- src/dashboard/AppSelector.react.js | 3 ++- src/dashboard/Apps/AppsIndex.react.js | 3 ++- src/dashboard/Data/ApiConsole/ApiConsole.react.js | 3 ++- src/dashboard/Data/Browser/Browser.react.js | 3 ++- src/dashboard/Data/Browser/CreateClassDialog.react.js | 3 ++- src/dashboard/Data/CloudCode/CloudCode.react.js | 3 ++- src/dashboard/Data/Jobs/Jobs.react.js | 3 ++- src/dashboard/Data/Logs/Logs.react.js | 3 ++- src/dashboard/Push/PushAudiencesIndex.react.js | 3 ++- src/dashboard/Push/PushDetails.react.js | 3 ++- src/dashboard/Push/PushIndex.react.js | 3 ++- src/dashboard/Push/PushNew.react.js | 3 ++- src/dashboard/Settings/GeneralSettings.react.js | 3 ++- src/parse-interface-guide/PIG.react.js | 3 ++- 16 files changed, 32 insertions(+), 16 deletions(-) diff --git a/src/components/FourOhFour/FourOhFour.react.js b/src/components/FourOhFour/FourOhFour.react.js index 3241947062..2e53789d92 100644 --- a/src/components/FourOhFour/FourOhFour.react.js +++ b/src/components/FourOhFour/FourOhFour.react.js @@ -11,7 +11,6 @@ import { withRouter } from 'lib/withRouter'; const EMOJI_COUNT = 30; -export default @withRouter class FourOhFour extends React.Component { constructor() { @@ -60,3 +59,5 @@ class FourOhFour extends React.Component { ); } } + +export default FourOhFour; diff --git a/src/dashboard/Analytics/Explorer/Explorer.react.js b/src/dashboard/Analytics/Explorer/Explorer.react.js index 56b7405719..728493d05d 100644 --- a/src/dashboard/Analytics/Explorer/Explorer.react.js +++ b/src/dashboard/Analytics/Explorer/Explorer.react.js @@ -39,7 +39,6 @@ let buildFriendlyName = (query) => { return name.join(' '); }; -export default @subscribeTo('AnalyticsQuery', 'customQueries') @withRouter class Explorer extends DashboardView { @@ -549,3 +548,5 @@ class Explorer extends DashboardView { ); } } + +export default Explorer; diff --git a/src/dashboard/AppSelector.react.js b/src/dashboard/AppSelector.react.js index be338ac071..c8e413e9b6 100644 --- a/src/dashboard/AppSelector.react.js +++ b/src/dashboard/AppSelector.react.js @@ -14,7 +14,6 @@ import Option from 'components/Dropdown/Option.react'; import React from 'react'; import { withRouter } from 'lib/withRouter'; -export default @withRouter class AppSelector extends React.Component { constructor(props) { @@ -60,3 +59,5 @@ class AppSelector extends React.Component { ); } } + +export default AppSelector; diff --git a/src/dashboard/Apps/AppsIndex.react.js b/src/dashboard/Apps/AppsIndex.react.js index 4324b932de..4b1d5efbd5 100644 --- a/src/dashboard/Apps/AppsIndex.react.js +++ b/src/dashboard/Apps/AppsIndex.react.js @@ -90,7 +90,6 @@ let AppCard = ({ } -export default @withRouter class AppsIndex extends React.Component { constructor() { @@ -173,3 +172,5 @@ class AppsIndex extends React.Component { ); } } + +export default AppsIndex; diff --git a/src/dashboard/Data/ApiConsole/ApiConsole.react.js b/src/dashboard/Data/ApiConsole/ApiConsole.react.js index dd11396839..513e26c683 100644 --- a/src/dashboard/Data/ApiConsole/ApiConsole.react.js +++ b/src/dashboard/Data/ApiConsole/ApiConsole.react.js @@ -11,7 +11,6 @@ import DashboardView from 'dashboard/DashboardView.react'; import { Outlet } from 'react-router-dom'; import { withRouter } from 'lib/withRouter'; -export default @withRouter class ApiConsole extends DashboardView { constructor() { @@ -40,3 +39,5 @@ class ApiConsole extends DashboardView { return ; } } + +export default ApiConsole; diff --git a/src/dashboard/Data/Browser/Browser.react.js b/src/dashboard/Data/Browser/Browser.react.js index f1065ecf3b..9cfecb36ba 100644 --- a/src/dashboard/Data/Browser/Browser.react.js +++ b/src/dashboard/Data/Browser/Browser.react.js @@ -41,7 +41,6 @@ import { withRouter } from 'lib/withRouter'; // The initial and max amount of rows fetched by lazy loading const MAX_ROWS_FETCHED = 200; -export default @subscribeTo('Schema', 'schema') @withRouter class Browser extends DashboardView { @@ -1786,3 +1785,5 @@ class Browser extends DashboardView { ); } } + +export default Browser; diff --git a/src/dashboard/Data/Browser/CreateClassDialog.react.js b/src/dashboard/Data/Browser/CreateClassDialog.react.js index fe6fbf912f..9c2747bccf 100644 --- a/src/dashboard/Data/Browser/CreateClassDialog.react.js +++ b/src/dashboard/Data/Browser/CreateClassDialog.react.js @@ -19,7 +19,6 @@ function validClassName(name) { return !!name.match(/^[a-zA-Z][_a-zA-Z0-9]*$/); } -export default @withRouter class CreateClassDialog extends React.Component { constructor() { @@ -103,3 +102,5 @@ class CreateClassDialog extends React.Component { ); } } + +export default CreateClassDialog; diff --git a/src/dashboard/Data/CloudCode/CloudCode.react.js b/src/dashboard/Data/CloudCode/CloudCode.react.js index 5fcb7f0154..8af0698389 100644 --- a/src/dashboard/Data/CloudCode/CloudCode.react.js +++ b/src/dashboard/Data/CloudCode/CloudCode.react.js @@ -19,7 +19,6 @@ function getPath(params) { return params.splat; } -export default @withRouter class CloudCode extends DashboardView { constructor() { @@ -131,3 +130,5 @@ class CloudCode extends DashboardView { ); } } + +export default CloudCode; diff --git a/src/dashboard/Data/Jobs/Jobs.react.js b/src/dashboard/Data/Jobs/Jobs.react.js index a21c05f06a..d163847db8 100644 --- a/src/dashboard/Data/Jobs/Jobs.react.js +++ b/src/dashboard/Data/Jobs/Jobs.react.js @@ -61,7 +61,6 @@ function scheduleString(data) { } // TODO: create scrollable view component that handles lazy fetch container on scroll -export default @subscribeTo('Jobs', 'jobs') @withRouter class Jobs extends TableView { @@ -301,3 +300,5 @@ class Jobs extends TableView { return null; } } + +export default Jobs; diff --git a/src/dashboard/Data/Logs/Logs.react.js b/src/dashboard/Data/Logs/Logs.react.js index 9b59059b83..27ce8eb8f6 100644 --- a/src/dashboard/Data/Logs/Logs.react.js +++ b/src/dashboard/Data/Logs/Logs.react.js @@ -22,7 +22,6 @@ let subsections = { error: 'Error' }; -export default @withRouter class Logs extends DashboardView { constructor() { @@ -123,3 +122,5 @@ class Logs extends DashboardView { ); } } + +export default Logs; diff --git a/src/dashboard/Push/PushAudiencesIndex.react.js b/src/dashboard/Push/PushAudiencesIndex.react.js index 2ca46b0a0b..1120719f29 100644 --- a/src/dashboard/Push/PushAudiencesIndex.react.js +++ b/src/dashboard/Push/PushAudiencesIndex.react.js @@ -30,7 +30,6 @@ import { withRouter } from 'lib/withRouter'; const XHR_KEY = 'PushAudiencesIndex'; -export default @subscribeTo('Schema', 'schema') @subscribeTo('PushAudiences', 'pushaudiences') @withRouter @@ -277,3 +276,5 @@ class PushAudiencesIndex extends DashboardView { ); } } + +export default PushAudiencesIndex; diff --git a/src/dashboard/Push/PushDetails.react.js b/src/dashboard/Push/PushDetails.react.js index 58d992b6bc..a560f492b5 100644 --- a/src/dashboard/Push/PushDetails.react.js +++ b/src/dashboard/Push/PushDetails.react.js @@ -200,7 +200,6 @@ const COLOR_MAP = { const DROPDOWN_KEY_GROUP_A = 'Group A'; const DROPDOWN_KEY_GROUP_B = 'Group B'; -export default @subscribeTo('Schema', 'schema') @withRouter class PushDetails extends DashboardView { @@ -745,3 +744,5 @@ class PushDetails extends DashboardView { ); } } + +export default PushDetails; diff --git a/src/dashboard/Push/PushIndex.react.js b/src/dashboard/Push/PushIndex.react.js index 3a9c4645da..79f39d55ff 100644 --- a/src/dashboard/Push/PushIndex.react.js +++ b/src/dashboard/Push/PushIndex.react.js @@ -227,7 +227,6 @@ let getPushTime = (pushTime, updatedAt) => { return result; } -export default @withRouter class PushIndex extends DashboardView { constructor() { @@ -449,3 +448,5 @@ class PushIndex extends DashboardView { ); } } + +export default PushIndex; diff --git a/src/dashboard/Push/PushNew.react.js b/src/dashboard/Push/PushNew.react.js index 612825975b..48b056f5dd 100644 --- a/src/dashboard/Push/PushNew.react.js +++ b/src/dashboard/Push/PushNew.react.js @@ -121,7 +121,6 @@ let LocalizedMessageField = ({ const XHR_KEY = 'PushNew'; -export default @subscribeTo('Schema', 'schema') @subscribeTo('PushAudiences', 'pushaudiences') @withRouter @@ -896,3 +895,5 @@ class PushNew extends DashboardView { }}/>; } } + +export default PushNew; diff --git a/src/dashboard/Settings/GeneralSettings.react.js b/src/dashboard/Settings/GeneralSettings.react.js index 6a15e3bf59..6ad7458e4b 100644 --- a/src/dashboard/Settings/GeneralSettings.react.js +++ b/src/dashboard/Settings/GeneralSettings.react.js @@ -337,7 +337,6 @@ let ManageAppFields = ({ ); } -export default @withRouter class GeneralSettings extends DashboardView { constructor() { @@ -800,3 +799,5 @@ let generalFieldsOptions = { friendlyName: 'other URL', }, }; + +export default GeneralSettings; diff --git a/src/parse-interface-guide/PIG.react.js b/src/parse-interface-guide/PIG.react.js index 766ec5955d..800ef521b1 100644 --- a/src/parse-interface-guide/PIG.react.js +++ b/src/parse-interface-guide/PIG.react.js @@ -20,7 +20,6 @@ let PIGRow = ({ title, children }) =>
{children}
; -export default @withRouter class PIG extends React.Component { constructor() { @@ -92,3 +91,5 @@ class PIG extends React.Component { ); } } + +export default PIG; From 7488dd83cebbc05d9b0dc6668db1fde634072b96 Mon Sep 17 00:00:00 2001 From: Damian Stasik <920747+damianstasik@users.noreply.github.com> Date: Sun, 25 Sep 2022 16:51:21 +0200 Subject: [PATCH 13/18] Spread outlet context as direct props --- src/lib/withRouter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/withRouter.js b/src/lib/withRouter.js index 898e0f6cd3..707c1a6e6e 100644 --- a/src/lib/withRouter.js +++ b/src/lib/withRouter.js @@ -8,7 +8,7 @@ export function withRouter(Component) { const outletContext = useOutletContext(); const location = useLocation(); - return ; + return ; } const name = Component.displayName || Component.name; From 485a1c91431e6757e66a0b29ff780059c51f4d89 Mon Sep 17 00:00:00 2001 From: Damian Stasik <920747+damianstasik@users.noreply.github.com> Date: Sun, 25 Sep 2022 16:51:42 +0200 Subject: [PATCH 14/18] Simplify link urls --- src/components/Sidebar/AppsMenu.react.js | 2 +- src/dashboard/Push/PushDetails.react.js | 2 +- src/dashboard/Settings/GeneralSettings.react.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Sidebar/AppsMenu.react.js b/src/components/Sidebar/AppsMenu.react.js index 62e906f3cd..cbee4edd80 100644 --- a/src/components/Sidebar/AppsMenu.react.js +++ b/src/components/Sidebar/AppsMenu.react.js @@ -23,7 +23,7 @@ const AppsMenu = ({ apps, current, height, onSelect, onPinClick }) => ( return null; } return ( - + {app.name} diff --git a/src/dashboard/Push/PushDetails.react.js b/src/dashboard/Push/PushDetails.react.js index a560f492b5..3ab30046bc 100644 --- a/src/dashboard/Push/PushDetails.react.js +++ b/src/dashboard/Push/PushDetails.react.js @@ -472,7 +472,7 @@ class PushDetails extends DashboardView { prevLaunchGroup = (
- This push is the Launch Group for a previous experiment. + This push is the Launch Group for a previous experiment.
); diff --git a/src/dashboard/Settings/GeneralSettings.react.js b/src/dashboard/Settings/GeneralSettings.react.js index 6ad7458e4b..9a9981ab54 100644 --- a/src/dashboard/Settings/GeneralSettings.react.js +++ b/src/dashboard/Settings/GeneralSettings.react.js @@ -306,7 +306,7 @@ let ManageAppFields = ({ {cloneAppMessage ? -
{cloneAppMessage} Check out the progress on your apps page!
+
{cloneAppMessage} Check out the progress on your apps page!
: null} {!isCollaborator ? Date: Sun, 25 Sep 2022 16:52:06 +0200 Subject: [PATCH 15/18] Avoid using global location, better to be safe and use one provided from router --- src/dashboard/AppSelector.react.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dashboard/AppSelector.react.js b/src/dashboard/AppSelector.react.js index c8e413e9b6..aba0f84ca7 100644 --- a/src/dashboard/AppSelector.react.js +++ b/src/dashboard/AppSelector.react.js @@ -26,7 +26,7 @@ class AppSelector extends React.Component { } handleConfirm() { - let newPath = location.pathname.replace(/\/_(\/|$)/, '/' + this.state.slug + '/'); + let newPath = this.location.pathname.replace(/\/_(\/|$)/, '/' + this.state.slug + '/'); this.props.navigate(newPath); } From 2a89cf7bcafeae5f31a7a2f0c49d58d41fa04509 Mon Sep 17 00:00:00 2001 From: Damian Stasik <920747+damianstasik@users.noreply.github.com> Date: Sun, 25 Sep 2022 16:52:25 +0200 Subject: [PATCH 16/18] Enable experimental decorators in js config to improve DX --- jsconfig.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jsconfig.json b/jsconfig.json index a40157ac93..4a810717ee 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -1,4 +1,7 @@ { + "compilerOptions": { + "experimentalDecorators": true + }, "typeAcquisition": { "include": [ "jest" From 85cf1082455f6685928c7d9d8b0dfa80624399b5 Mon Sep 17 00:00:00 2001 From: Damian Stasik <920747+damianstasik@users.noreply.github.com> Date: Sun, 25 Sep 2022 17:28:56 +0200 Subject: [PATCH 17/18] Bring back old separation to see if PR diff would be easier to understand --- src/dashboard/Dashboard.js | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/dashboard/Dashboard.js b/src/dashboard/Dashboard.js index 7707fed6e1..1c9a740c10 100644 --- a/src/dashboard/Dashboard.js +++ b/src/dashboard/Dashboard.js @@ -197,7 +197,18 @@ export default class Dashboard extends React.Component { ); - const BrowserRoute = () => ShowSchemaOverview ? : ; + const SettingsRoute = ( + }> + } /> + } /> + } /> + } /> + } /> + } /> + + ) + + const BrowserRoute = ShowSchemaOverview ? SchemaOverview : Browser; return ( @@ -255,24 +266,19 @@ export default class Dashboard extends React.Component { {/* Unused routes... */} - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> } /> } /> - }> - } /> - } /> - } /> - } /> - } /> - } /> - + + {SettingsRoute} + From 308f987718cc17cc74c25311001f1b7979e7c582 Mon Sep 17 00:00:00 2001 From: Damian Stasik <920747+damianstasik@users.noreply.github.com> Date: Sun, 25 Sep 2022 17:43:48 +0200 Subject: [PATCH 18/18] Bring back old structure, plan is to refactor it to useRoutes in a separate PR --- src/dashboard/Dashboard.js | 140 ++++++++++++++++++++++--------------- 1 file changed, 82 insertions(+), 58 deletions(-) diff --git a/src/dashboard/Dashboard.js b/src/dashboard/Dashboard.js index 1c9a740c10..3a639cdb79 100644 --- a/src/dashboard/Dashboard.js +++ b/src/dashboard/Dashboard.js @@ -208,83 +208,107 @@ export default class Dashboard extends React.Component { ) - const BrowserRoute = ShowSchemaOverview ? SchemaOverview : Browser; + const JobsRoute = ( + }> + } /> + } /> + } /> + } /> + + ) - return ( - - - Parse Dashboard - - - } /> + const AnalyticsRoute = ( + + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + ) - - } /> + const BrowserRoute = ShowSchemaOverview ? SchemaOverview : Browser; - }> - } /> + const ApiConsoleRoute = ( + }> + } /> + } /> + } /> + } /> + + ) - } /> + const AppRoute = ( + }> + } /> - } /> - } /> - } /> + } /> - } /> - } /> - } /> + } /> + } /> + } /> - }> - } /> - } /> - } /> + } /> + } /> + } /> - } /> - + + {JobsRoute} + - } /> - } /> + } /> + } /> - } /> + } /> - }> - } /> - } /> - } /> - } /> - + + {ApiConsoleRoute} + - } /> + } /> - } /> - } /> + } /> + } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> - {/* Unused routes... */} - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - + {/* Unused routes... */} + + {AnalyticsRoute} + + + {SettingsRoute} + + + ) - - {SettingsRoute} - - - + const Index = ( + + } /> + + {AppRoute} + + + ) - } /> + return ( + + + Parse Dashboard + + + + {Index} + } /> - + } /> + } /> } />