Skip to content

Commit e73a129

Browse files
authored
Merge pull request #7311 from skateman/dynamic-schema-select
Add onChange functionality to our DDF select fields
2 parents bee2cdc + 564596d commit e73a129

File tree

4 files changed

+56
-48
lines changed

4 files changed

+56
-48
lines changed

app/javascript/components/provider-form/index.jsx

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import MiqFormRenderer from '../../forms/data-driven-form';
88
import miqRedirectBack from '../../helpers/miq-redirect-back';
99
import mapper from '../../forms/mappers/componentMapper';
1010
import ProtocolSelector from './protocol-selector';
11-
import ProviderSelectField from './provider-select-field';
1211
import ProviderCredentials from './provider-credentials';
1312
import ValidateProviderCredentials from './validate-provider-credentials';
1413
import DetectButton from './detect-button';
@@ -19,19 +18,6 @@ const findSkipSubmits = (schema, items) => {
1918
return [...found, ...children];
2019
};
2120

22-
const typeSelectField = (edit, filter) => ({
23-
component: 'provider-select-field',
24-
id: 'type',
25-
name: 'type',
26-
label: __('Type'),
27-
kind: filter,
28-
isDisabled: edit,
29-
loadOptions: () =>
30-
API.options('/api/providers').then(({ data: { supported_providers } }) => supported_providers // eslint-disable-line camelcase
31-
.filter(({ kind }) => kind === filter)
32-
.map(({ title, type }) => ({ value: type, label: title }))),
33-
});
34-
3521
const commonFields = [
3622
{
3723
component: componentTypes.TEXT_FIELD,
@@ -58,7 +44,7 @@ const commonFields = [
5844
},
5945
];
6046

61-
export const loadProviderFields = (kind, type) => API.options(`/api/providers?type=${type}`).then(
47+
const loadProviderFields = type => API.options(`/api/providers?type=${type}`).then(
6248
({ data: { provider_form_schema } }) => ([ // eslint-disable-line camelcase
6349
...commonFields,
6450
{
@@ -70,11 +56,27 @@ export const loadProviderFields = (kind, type) => API.options(`/api/providers?ty
7056
]),
7157
);
7258

59+
const typeSelectField = (edit, filter, setState) => ({
60+
component: 'select',
61+
id: 'type',
62+
name: 'type',
63+
label: __('Type'),
64+
kind: filter,
65+
isDisabled: edit,
66+
loadOptions: () =>
67+
API.options('/api/providers').then(({ data: { supported_providers } }) => supported_providers // eslint-disable-line camelcase
68+
.filter(({ kind }) => kind === filter)
69+
.map(({ title, type }) => ({ value: type, label: title }))),
70+
onChange: value => loadProviderFields(value).then(fields => setState(({ fields: [firstField] }) => ({
71+
fields: [firstField, ...fields],
72+
}))),
73+
});
74+
7375
export const EditingContext = React.createContext({});
7476

7577
const ProviderForm = ({ providerId, kind, title, redirect }) => {
7678
const edit = !!providerId;
77-
const [{ fields, initialValues }, setState] = useState({ fields: edit ? undefined : [typeSelectField(false, kind)] });
79+
const [{ fields, initialValues }, setState] = useState({});
7880

7981
const submitLabel = edit ? __('Save') : __('Add');
8082

@@ -94,7 +96,7 @@ const ProviderForm = ({ providerId, kind, title, redirect }) => {
9496
const endpoints = keyBy(_endpoints, 'role');
9597
const authentications = keyBy(_authentications, 'authtype');
9698

97-
loadProviderFields(kind, type).then((fields) => {
99+
loadProviderFields(type).then((fields) => {
98100
setState({
99101
fields: [typeSelectField(true, kind), ...fields],
100102
initialValues: {
@@ -106,6 +108,10 @@ const ProviderForm = ({ providerId, kind, title, redirect }) => {
106108
});
107109
}).then(miqSparkleOff);
108110
});
111+
} else {
112+
// As the typeSelectField relies on the setState() function, it's necessary to set the initial state
113+
// here and not above in the useState() function.
114+
setState({ fields: [typeSelectField(false, kind, setState)] });
109115
}
110116
}, [providerId]);
111117

@@ -154,7 +160,6 @@ const ProviderForm = ({ providerId, kind, title, redirect }) => {
154160
const componentMapper = {
155161
...mapper,
156162
'protocol-selector': ProtocolSelector,
157-
'provider-select-field': ProviderSelectField,
158163
'provider-credentials': ProviderCredentials,
159164
'validate-provider-credentials': ValidateProviderCredentials,
160165
'detect-button': DetectButton,

app/javascript/components/provider-form/provider-select-field.jsx

Lines changed: 0 additions & 28 deletions
This file was deleted.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
import React, { useEffect } from 'react';
3+
import PropTypes from 'prop-types';
4+
import { components } from '@data-driven-forms/pf3-component-mapper';
5+
6+
import { useFieldApi } from '@@ddf';
7+
8+
const SelectWithOnChange = ({ onChange, ...props }) => {
9+
if (onChange) {
10+
const { input: { value } } = useFieldApi(props);
11+
12+
useEffect(() => {
13+
if (!props.isDisabled && value) {
14+
onChange(value);
15+
}
16+
}, [value]);
17+
}
18+
19+
return <components.Select placeholder={`<${__('Choose')}>`} {...props} />;
20+
};
21+
22+
SelectWithOnChange.propTypes = {
23+
onChange: PropTypes.func,
24+
};
25+
26+
SelectWithOnChange.defaultProps = {
27+
onChange: undefined,
28+
};
29+
30+
export default SelectWithOnChange;

app/javascript/forms/mappers/componentMapper.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import React from 'react';
2-
import { componentMapper, components } from '@data-driven-forms/pf3-component-mapper';
2+
import { componentMapper } from '@data-driven-forms/pf3-component-mapper';
33
import { componentTypes } from '@@ddf';
44

55
import AsyncCredentials from '../../components/async-credentials/async-credentials';
66
import DualGroup from '../../components/dual-group';
77
import DualListSelect from '../../components/dual-list-select';
88
import EditPasswordField from '../../components/async-credentials/edit-password-field';
99
import PasswordField from '../../components/async-credentials/password-field';
10+
import Select from '../../components/select';
1011
import { DataDrivenFormCodeEditor } from '../../components/code-editor';
1112
import FieldArray from '../../components/field-array';
1213

@@ -21,7 +22,7 @@ const mapper = {
2122
note: props => <div className={props.className} role="alert">{props.label}</div>,
2223
'password-field': PasswordField,
2324
'validate-credentials': AsyncCredentials,
24-
[componentTypes.SELECT]: props => <components.Select placeholder={`<${__('Choose')}>`} {...props} />,
25+
[componentTypes.SELECT]: Select,
2526
};
2627

2728
export default mapper;

0 commit comments

Comments
 (0)