Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEP Upgrade front-end build stack #1389

Merged
merged 5 commits into from
Dec 18, 2022

Conversation

GuySartorelli
Copy link
Member

@GuySartorelli GuySartorelli force-pushed the pulls/2/update-webpack branch 2 times, most recently from 78917e7 to 7d90c21 Compare November 15, 2022 03:42
@GuySartorelli GuySartorelli mentioned this pull request Nov 15, 2022
@GuySartorelli GuySartorelli force-pushed the pulls/2/update-webpack branch 4 times, most recently from 4d2ee22 to b75a11c Compare December 2, 2022 03:08
@GuySartorelli GuySartorelli force-pushed the pulls/2/update-webpack branch 7 times, most recently from 3551c29 to 139e179 Compare December 8, 2022 01:46
Comment on lines -23 to +25
this.setState({
isOpen: !this.state.isOpen
});
// Force setting state to the end of the execution queue to clear a potential race condition
// with entwine click handlers
window.setTimeout(() => this.setState({ isOpen: !this.state.isOpen }), 0);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added this in a couple of places defensively - the only place I know for certain it's needed is this one.
The race condition occurs like this:

  1. User clicks the button
  2. React responds first.
    1. React toggles the menu to close, which removes the button that was clicked
  3. Entwine wants to respond to the event, but the button isn't in the DOM so it doesn't.

This solution works because it defers closing the dropdown (and thus removing the button) until the next event cycle (see the MDN docs for setTimeout). This allows the current event cycle to continue (and therefore lets entwine respond to the click event) before closing closing the dropdown.
More about the event loop can be read in MDN's docs on the subject.

@GuySartorelli GuySartorelli force-pushed the pulls/2/update-webpack branch 2 times, most recently from 1631d6c to 8c2bebf Compare December 12, 2022 03:12
Comment on lines -188 to +189
expect(inputField.value).toBe('2017-01-05T02:23');
// Note that the inclusion of seconds or milliseconds is unnecessary but acceptable
expect(inputField.value).toMatch(/^2017-01-05T02:23(:22|:22.000)?$/);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test was failing because the value included the seconds and milliseconds. The actual functionality was fine, as this is still a valid ISO format.

Comment on lines -9 to -22
constructor(props) {
super(props);

this.toggle = this.toggle.bind(this);
this.state = {
dropdownOpen: false
};
}

toggle() {
this.setState({
dropdownOpen: !this.state.dropdownOpen
});
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The toggle method and dropdownOpen state were never being referenced anywhere so I've removed them.

Comment on lines +5 to +10
/**
* This component can be used whenever a component which needs a relative link
* might be rendered in both context within a router (e.g. asset admin) and
* contexts without a router (e.g. inside an image upload modal).
*/
function Link({ children, href, ...props }) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is necessary because the update of react-router resulted in the way routes are added being changed - where the route and url both used to be e.g. /admin/assets/show/1/edit, the route is now relative to the base route, e.g. assets/show/1/edit. This means we have to use a react Link component when in a react router context so that the correct full path is on the rendered <a> tag's href attribute..

@@ -8,7 +8,7 @@ import PropTypes from 'prop-types';
*
* Adapted from https://github.com/FezVrasta/react-resize-aware created by Federico Zivolo.
*/
export default class ResizeAware extends Component {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move export to after the proptypes and defaultprops are declared.


return <CacheProvider value={cache}>{children}</CacheProvider>;
}

class TreeDropdownField extends Component {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of the changes in this class are a result of changes in the API for react-select.
See the upgrade guides here: https://react-select.com/upgrade we went from v1 all the way to v5.

* Render the breadcrumbs.
* This sits above the options in nested trees, as a way to navigate back
*/
renderBreadcrumbs(breadcrumbs, { cx, getStyles, getClassNames, ...props }) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This used to be in TreeDropdownFieldMenu which is no longer needed.

: title;
}

noOptionsMessage({ inputValue }) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This used to be in TreeDropdownFieldMenu which is no longer needed.

}

const resetValue = (this.props.data.hasEmptyDefault && !this.props.visible.length)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer needed

<div className="app">{renderRoutes(route.routes())}</div>
<div className="app"><Outlet /></div>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rendering the routes is no longer the responsibility of this component. It's handled by BootRoutes.js explicitly.

Comment on lines -72 to +78
ReactDOM.render(
let root = this.getReactRoot();
if (!root) {
root = createRoot(this[0]);
}
root.render(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReactDOM.render was deprecated in react 17 and removed in react 18. It would still technically work but it would result in react behaving like it was still v17. See this blog post for more details.
See also _clearModal() below for the replacement of the old ReactDOM.unmountComponentAtNode() method.

jest.mock('../MiddlewareRegistry', () => () => ({ add: jest.fn() }));
jest.mock('../MiddlewareRegistry', () => jest.fn().mockImplementation(() => ({ add: () => {} })));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was necessary to fix an error where the mocked class wasn't being returned correctly. The error was along the lines of MiddlewareRegistry is not a constructor

@GuySartorelli
Copy link
Member Author

JS CI build failed due to broken tests and linting errors. Those will be handled separately, see #1421 and #1411

@emteknetnz emteknetnz merged commit 2b8f53e into silverstripe:2 Dec 18, 2022
@emteknetnz emteknetnz deleted the pulls/2/update-webpack branch December 18, 2022 21:19
This was referenced Jan 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants