Skip to content

Conversation

@skateman
Copy link
Member

@skateman skateman commented Sep 16, 2020

This is a generalization of the ProviderSelectField that is being used in the provider forms to load the provider schema based on the user's selection in a dropdown. I adjusted the component and the provider form to solely rely on attributes passed to the schema instead of using a react context. We are using the PF3 select with a custom placeholder which has been defined directly in the mapper. In order to avoid circular dependencies, I exported this into a separate file and. Then I renamed the component and moved it out to the global mapper so we can utilize it in other forms as well.

The dynamic loadin' is sorted out via the onChange function that gets called on any change in the dropdown with the new value as a single argument. Ideally this can be used together with the state to alter the schema as we do it in the provider forms.

const [fields, setFields] = useState([]);

const dynamicSelect = {
  component: 'select',
  name: 'type',
  label: 'Type',
  options: [{label: 'a', value: 'a'}, {label: 'b', value: 'b'}],
  onChange: value => {
    API.get(`/foo/bar&value=${value}`).then(data => setFields(data.fields)),
  },
};

<MiqFormRenderer ... schema={{ fields: [dynamicSelect, ...fields] }} />

@DavidResende0 this is how we're going to load the fields from the API if @himdel agrees

@skateman skateman force-pushed the dynamic-schema-select branch from 7a3eada to 085bc05 Compare September 16, 2020 10:35
@himdel
Copy link
Contributor

himdel commented Sep 16, 2020

How does a select have a "schema"? It should have options, but it already has static options in your example,
so what does the schema actually do in the select?

Reading the example, that "schema" is not actually related to the select at all, in fact it just changes the rest of the form.

IMO that's architecturally wrong, the form itself (our react component wrapping MiqFormRenderer), should be doing that kind of logic.

A form field should not be affecting other form fields from inside itself.

@skateman
Copy link
Member Author

@himdel there's already an example of this in the provider forms: when you select what kind of provider you want to create, we send an API request to retrieve the schema related to the given provider. If you don't like the name of the component, I'm open for better ideas, this is again the problem of starting a metal band.

@himdel
Copy link
Contributor

himdel commented Sep 16, 2020

No, my problem is not with the name, it's with one component changing the whole form schema, instead of the form changing the schema depending on the value from that component.

EDIT: or a select-with-a-subform where that select only affects the subform schema

But If you're just refactoring that for some other use, go for it 👍.
IMHO it should not exist in the first place.

@skateman
Copy link
Member Author

No, my problem is not with the name, it's with one component changing the whole form schema, instead of the form changing the schema depending on the value from that component.

If you're just refactoring that for some other use, go for it.
But it should not exist in the first place.

The component is not changing anything, the function is defined in the form and passed to the component for calling it when its value changes. This is just an uglier onChange function, I can even rename it to onChange if it doesn't drive the renderer crazy (but I'm worried it would). We could listen to changes from the outside using the debug attribute on the MiqFormRenderer but IMO that's something we should avoid. We could also create a FormSpy but that needs to live inside the form as well and it's less effective as it cannot just subscribe to the changes of a single field. So AFAIK this is the most effective way to deal with API-provided schema changes in DDF which we really need and not just for the provider forms.

@himdel
Copy link
Contributor

himdel commented Sep 16, 2020

Oooh.. ok, then select-with-onchange probably makes more sense, yeah 👍

@skateman skateman force-pushed the dynamic-schema-select branch from 085bc05 to 7c025b2 Compare September 16, 2020 13:03
@skateman
Copy link
Member Author

@himdel updated

@skateman
Copy link
Member Author

I'm thinking that maybe we can just simply enhance the existing Select component (as it is already customized) with a conditional useEffect (not sure if possible) that would be called when the onChange attribute is set. This way we don't need the exotic component name. WDYT @himdel

@skateman skateman changed the title Select component that loads additional DDF fields dynamically Add onChange functionality to our DDF select fields Sep 21, 2020
@himdel
Copy link
Contributor

himdel commented Sep 21, 2020

LGTM :) reimplements the provider select field on top of a new select with an onchange handler exposed.

I'm thinking that maybe we can just simply enhance the existing Select component (as it is already customized) with [onChange]

Up to you :) Then we would have a select that supports onChange, while none of the other standard components do, but then again, it makes sense to have it in the select. OTOH one more custom thing to remember.

@skateman skateman force-pushed the dynamic-schema-select branch from 7c025b2 to 564596d Compare September 21, 2020 14:19
@miq-bot
Copy link
Member

miq-bot commented Sep 21, 2020

Checked commits skateman/manageiq-ui-classic@4dc7048~...564596d with ruby 2.6.3, rubocop 0.69.0, haml-lint 0.28.0, and yamllint
0 files checked, 0 offenses detected
Everything looks fine. ⭐

@skateman
Copy link
Member Author

@himdel changed, I guess it's ready for the final round

@himdel himdel merged commit e73a129 into ManageIQ:master Sep 23, 2020
@skateman skateman deleted the dynamic-schema-select branch September 23, 2020 13:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants