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

Fixes #37454 - Allow js to be loaded late for react_component #10167

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

MariaAga
Copy link
Member

When js component is loaded after a user interaction, for example in app/views/compute_attributes/_compute_form.html.erb
the react_component does not wait for it to be loaded and does not show it.

Found it when a plugin had:

<%= webpacked_plugins_js_for :foreman_fog_proxmox %>
<%= react_component(...%>

in app/views/hosts/_compute_detail.html.erb

This makes this error to not ever happen: and to always assume that something is not loaded but will be, which is why I left the warning, so the console will still have the info

throw new Error(
`Component not found: ${name} among ${this.registeredComponents()}`
);

@MariaAga
Copy link
Member Author

@ShimShtein @jeremylenz What do you think of this solution? We resolved it in the plugin to load webpack on host load, and not when the compute resource changes but I think we should also have it resolved in core

@ShimShtein
Copy link
Member

If I understand correctly your code, you try to load a component, and if the component is missing, you assume that it was not loaded yet, so you set the allPluginsImported state to false and wait for the pluginLoaded event.

Maybe we should just use the global allPluginsLoaded or allJsLoaded as the trigger for component loading. To make sure the global object state is set correctly, we should set it to false as the first step in webpacked_plugins_js_for method. This way the sequence will be: call webpacked_plugins_js_for -> set allJsLoaded to false -> start loading the script -> draw the AwaitedLoad component -> wait for the allJsLoaded -> finish loading the script -> set allJsLoaded back to true -> Start drawing the component from the AwaitedLoad.

@MariaAga
Copy link
Member Author

@ShimShtein the issue comes where webpack loads a plugin after a user interaction, so host create page is loaded, all js is loaded, awaited components are all loaded, user selects a compute resource, more js scripts are loaded and at the same time the awaited component thinks everything was already loaded and fails

@ShimShtein
Copy link
Member

@MariaAga Yeah, I understand. My idea is to reset the "everything loaded" state once a request for more JS is executed. Then when the new portion of JS will be done loading, we will set the "everything loaded to true again.

Basically it means that our JS loading process should be: reset the "all loaded" state -> load the JS -> wait for it to finish loading -> set the "all loaded" flag again. I want to get to this sequence:

  1. First part of the page is loaded
  2. allLoaded = true
  3. Component requests for more JS
  4. allLoaded = false
  5. Load the additional JS
  6. Load the additional component as part of the JS package that is being loaded and set it to track allLoaded
  7. finish loading the additional JS
  8. allLoaded = true
  9. the additional component is unblocked and can be redrawn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants