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

Switch to React from react-lite #9263

Merged
merged 14 commits into from
Sep 23, 2018
Merged

Conversation

mareklibra
Copy link
Contributor

@mareklibra mareklibra commented May 29, 2018

The react-lite is slowly becoming obsolete compared to the recent react version 16.4 and
there are recently no plans to add support of v16 features to the react-lite [1].

Fixes to various so far found issues are provided.

One of the first benefits of this change is alignment of Cockpit with requirements of paternfly-react library.

Some of the issues related to React 15 -> 16 upgrade can be found in [2] .

To use development version of React:

./autogen.sh --enable-debug
make

[1] Lucifier129/react-lite#126
[2] https://reactjs.org/blog/2017/09/26/react-v16.0.html

List of follow-ups:

  • remove commented out code in cockpit-components-listing.jsx
  • redesign show_modal_dialog
  • check-{machines|ovir} - provide infra for setting checkbox value
  • pkg/storage - refactor component hierarchy of LogsPanel and content-views.jsx:block_rows()
  • test/check-* - provide infra for setting form fields rendered by React - text input, checkbox, etc.

PR split - following will be removed from here and merged separately:

Manual UI click arounds

  • System: Hardware Info
  • Logs
  • Storage
  • Networking
  • Containers
  • Machines (libvirt) - some issues found (see below)
  • Machines (ovirt)
  • Accounts
  • Services
  • Applications
  • Diagnostics Reports
  • Kernel Dump
  • SELinux
  • Software Updates
  • Subscriptions
  • Terminal

Issues found so far

  • Tooltip placement on Storage page (it's correct on e. g. Software Updates)
  • Machines: create: cannot toggle "immediately start VM" check box
  • Machines: switching to serial console crashes with TypeError: this.state.terminal.renderer is undefined (Oops happens with current master too, but at least the terminal appears)
  • Subscription register dialog is unresponsive, can't type into text fields.

@mareklibra
Copy link
Contributor Author

Waiting for tests to see remainers.

So far verified on my local dev environment, farther testing is needed.

Please build with ./autogen.sh --enable-debug to use development version of React - i.e. propType checking and better error messages are available.

@mareklibra mareklibra changed the title Switch to React from react-lite WIP: Switch to React from react-lite May 29, 2018
if (!this.props.children || this.props.children.length === 0) {
headerClasses = "listing-ct-empty";
headerRow = <tr><td>{this.props.emptyCaption}</td></tr>;
} else if (this.props.columnTitles.length) {
/* probably not needed, ListingRow.selected prop should be set to 'false' by default
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Keeping it here for simpler revert if I'm wrong.

Will be removed later if no issue found.

body: React.PropTypes.element.isRequired,
footer: React.PropTypes.element.isRequired,
id: React.PropTypes.string,
title: PropTypes.string, // required, but show_modal_dialog provides it after initial rendering; TODO: fix
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would prefer to fix the modal dialog in a follow-up.
Maybe by using patternfly-react's component for it but various Cockpit's use cases needs to be considered.

</Select.StatelessSelect>
</td>
</tr>
<tbody>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

React is more strict about element nesting ...

@@ -408,7 +408,7 @@ class TestMachines(MachineCase):
b.wait_present("#slate-header")
b.wait_in_text("#slate-header", "Virtualization Service (libvirt) is Not Active")
b.wait_present("#enable-libvirt:checked")
b.set_checked("#enable-libvirt", False)
b.click("#enable-libvirt") # uncheck it ; ; TODO: fix this, do not assume initial state of the checkbox
Copy link
Contributor Author

@mareklibra mareklibra May 31, 2018

Choose a reason for hiding this comment

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

I prefer follow-up to fix this.

@mareklibra mareklibra force-pushed the react branch 2 times, most recently from 0cb84e4 to f3f2694 Compare June 1, 2018 06:15
@mareklibra
Copy link
Contributor Author

Reactifying continues. This time storaged.

@mareklibra
Copy link
Contributor Author

Failing check-machines: testCreate on rhel-7 is fixed by #9304

@mareklibra
Copy link
Contributor Author

#9304 is merged, restarting tests

@mareklibra mareklibra force-pushed the react branch 2 times, most recently from aeb398c to 811f96a Compare June 7, 2018 08:57
@martinpitt
Copy link
Member

@mareklibra : Thanks for working on this! One hint, if you want to land this faster: A lot, or even most, commits also apply to react-lite, so they could land in a separate PR. This gets easier to review and validate in several smaller steps, and then the actual switch to React can happen separately.

var Listing = require('cockpit-components-listing.jsx');
var Select = require('cockpit-components-select.jsx');
var moment = require('moment');

var Dropdown = React.createClass({
var Dropdown = createReactClass({
Copy link
Member

Choose a reason for hiding this comment

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

This is already processed as ES6, so this could also just use the normal class .. extends React.Component syntax, couldn't it? Also, it could use import instead of var .. require? Or does that require even more intrusive changes? If so, then fine to do this intermediate step.

Copy link
Contributor Author

@mareklibra mareklibra Jun 8, 2018

Choose a reason for hiding this comment

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

Since this PR is about to be split into smaller ones now, we can afford this kind of refactoring.
Originally I skipped that to ease review.

I hope I'm not wrong, but I expect just syntax changes with this replacement.

@mareklibra
Copy link
Contributor Author

A lot, or even most, commits also apply to react-lite, so they could land in a separate PR.

This task became much bigger than originally expected. This will help.

mareklibra and others added 8 commits September 19, 2018 10:25
React does this automatically in a high-performance way,
so this call is not needed in this context.
PropTypes were moved to separate npm package 'prop-types' from core 'React'.

This patch is part of "react-lite to React" series.
So far, the PropTypes where just declared but not actually used.
Bunch of inconsistencies are expected, fixes will follow in next patches.
The `React.createClass` has been removed from React.

For legacy code, there's `create-react-class` npm package.
The react-lite library keeps compatibility with React 15.x which
is slowly deprecating.

Various Cockpit's npm dependencies are starting to require React 16
features, namely i.e. patternfly-react.

Closes cockpit-project#9263
- More "key" properties
- A <tbody> for each <table>
- Don't bind methods
React wont allow it; setting the "value" attribute will not be
reflected in the "value" property for arbitrary divs.  So we make this
more explicit by using a custom attribute.
Use Browser.set_input_text as appropriate.
@martinpitt
Copy link
Member

Pushed a rebase to fix the current conflicts.

@martinpitt
Copy link
Member

I'm at an impasse with the console crash. This is known issue #9641 again, it just crashes a lot harder now. @patternfly/react-console 1.4.2 contains the fix, but it also pulls in @novnc/novnc, and that causes an error:

SyntaxError: export declarations may only appear at top level of a module

here in the generated machines.js webpack:

/***/ function(module, exports) {

	/*
	 * noVNC: HTML5 VNC client
	 * Copyright (C) 2012 Joel Martin
	 * Licensed under MPL 2.0 (see LICENSE.txt)
	 *
	 * See README.md for usage and integration instructions.
	 */
	
	/*
	 * Logging/debug routines
	 */
	
	var _log_level = 'warn';
	
	var Debug = function (msg) {};
	var Info = function (msg) {};
	var Warn = function (msg) {};
	var Error = function (msg) {};
	
	export function init_logging (level) {

This fixes the pesky crash at last.

This pulls in @novnc/novnc, which uses ES6 syntax in its *.js files.
This leads to runtime errors like

    SyntaxError: export declarations may only appear at top level of a module

as these are embedded in webpacks. Until we update to a less ancient
weback, fix these by applying babel on the novnc sources.
@martinpitt
Copy link
Member

I bent the new PF-reactconsole to my will, and it's behaving correctly now. Yay for that crash being gone at last!

- Added "key" properties and "tbody" elements as necessary
- "Listing" wants an array of actions
- The "event" structure given to a handler is only valid while the handler runs
@mvollmer
Copy link
Member

Tooltip placement is off.

I can not reproduce this anymore. :-/

- "key" properties and "tbody" elements as necessary
- Form elements must be re-rendered on every change
- use StatelessSelect as required by the re-rendering
- Use Browser.set_input_text instead of set_val
@mvollmer mvollmer force-pushed the react branch 3 times, most recently from 0e8fcba to 3d3adde Compare September 21, 2018 10:50
- Use strings for "key" properties.

- Construct a new dialog body when values change, a render() call is
  not enough.

- Plumb "startVm" thtough the state as well to ensure re-rendering.

- Be sure to set text input values always to a string (and not
  "undefined") so that React will always treat them as controlled
  components.

- Use "className" instead of "extraClass", which is not a thing.  The
  additional class doesn't seem to have any effect, though.
- Pass a empty values for required properties instead of "undefined".
@martinpitt
Copy link
Member

Whee, all green and all TODOs done 🎉 Nice job everyone!

@martinpitt martinpitt merged commit 46612ec into cockpit-project:master Sep 23, 2018
martinpitt pushed a commit that referenced this pull request Sep 23, 2018
The react-lite library keeps compatibility with React 15.x which
is slowly deprecating.

Various Cockpit's npm dependencies are starting to require React 16
features, namely i.e. patternfly-react.

Closes #9263
garrett pushed a commit to garrett/cockpit that referenced this pull request Oct 17, 2018
The react-lite library keeps compatibility with React 15.x which
is slowly deprecating.

Various Cockpit's npm dependencies are starting to require React 16
features, namely i.e. patternfly-react.

Closes cockpit-project#9263
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.

4 participants