-
Notifications
You must be signed in to change notification settings - Fork 74
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
[settings] New integration settings component #1315
Changes from all commits
c9de4e2
daf1355
83b3469
0a7534c
6cf06eb
762d796
5d9e091
e1a3fd6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
import 'patternflyStyles/settingsPage' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
// @flow | ||
|
||
export * from 'Form/FormFieldset' | ||
export * from 'Form/FormLegend' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// @flow | ||
|
||
import * as React from 'react' | ||
import { FormFieldset, FormLegend } from 'Form' | ||
import { FormCollection, TextInputGroup } from 'Settings/components/Common' | ||
import { OidcFieldset } from 'Settings/components/OidcFieldset' | ||
import type { FieldGroupProps, TypeItemProps } from 'Settings/types' | ||
|
||
const OIDC_AUTH_METHOD = 'oidc' | ||
const API_KEY_METHOD = '1' | ||
const APP_ID_KEY_METHOD = '2' | ||
|
||
type Props = { | ||
isServiceMesh: boolean, | ||
authenticationMethod: string, | ||
apiKeySettings: FieldGroupProps, | ||
appIdKeyPairSettings: FieldGroupProps[], | ||
oidcSettings: { | ||
basicSettings: TypeItemProps, | ||
flowSettings: FieldGroupProps[], | ||
jwtSettings: TypeItemProps | ||
} | ||
} | ||
|
||
const AuthenticationSettingsFieldset = ({ | ||
isServiceMesh, | ||
authenticationMethod, | ||
apiKeySettings, | ||
appIdKeyPairSettings, | ||
oidcSettings | ||
}: Props) => { | ||
const isOidc = authenticationMethod === OIDC_AUTH_METHOD | ||
const isApiKey = authenticationMethod === API_KEY_METHOD | ||
const isAppIdKey = authenticationMethod === APP_ID_KEY_METHOD | ||
return ( | ||
(!isServiceMesh || isOidc) && <FormFieldset id='fieldset-AuthenticationSettings'> | ||
<FormLegend>Authentication Settings</FormLegend> | ||
{ isApiKey && <FormCollection collection={[apiKeySettings]} ItemComponent={TextInputGroup} legend='API KEY (USER_KEY) BASICS' /> } | ||
{ isAppIdKey && <FormCollection collection={appIdKeyPairSettings} ItemComponent={TextInputGroup} legend='APP_ID AND APP_KEY PAIR BASICS' /> } | ||
{ isOidc && <OidcFieldset {...oidcSettings} isServiceMesh={isServiceMesh} /> } | ||
</FormFieldset> | ||
) | ||
} | ||
|
||
export { | ||
AuthenticationSettingsFieldset | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// @flow | ||
|
||
import * as React from 'react' | ||
import { FormFieldset, FormLegend } from 'Form' | ||
import type { FieldGroupProps } from 'Settings/types' | ||
|
||
type Props = { | ||
collection: FieldGroupProps[], | ||
ItemComponent: (FieldGroupProps) => React.Element<empty>, | ||
legend: string | ||
} | ||
|
||
const FormCollection = ({collection, ItemComponent, legend}: Props) => { | ||
return ( | ||
<FormFieldset id={`fieldset-${legend.replace(/\s+/g, '')}`}> | ||
<FormLegend>{legend}</FormLegend> | ||
{ collection.map(itemProps => <ItemComponent {...itemProps} key={itemProps.name} />) } | ||
</FormFieldset> | ||
) | ||
} | ||
|
||
export { | ||
FormCollection | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// @flow | ||
|
||
import * as React from 'react' | ||
import { useState } from 'react' | ||
import { FormFieldset, FormLegend } from 'Form' | ||
import { Radio } from '@patternfly/react-core' | ||
import type { FieldGroupProps, FieldCatalogProps } from 'Settings/types' | ||
|
||
type CheckEvent = SyntheticEvent<HTMLButtonElement> | ||
|
||
type Props = FieldGroupProps & FieldCatalogProps | ||
|
||
const useSelectedOnChange = (value, onChange) => ( | ||
typeof onChange === 'function' | ||
? [value, onChange] | ||
: useState(value).map(x => typeof x === 'function' ? (_c, e: CheckEvent) => x(e.currentTarget.value) : x) | ||
didierofrivia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
|
||
const RadioFieldset = ({ | ||
children, | ||
legend, | ||
name, | ||
value, | ||
catalog, | ||
onChange, | ||
...props | ||
}: Props) => { | ||
const [selectedOnChange, setSelectedOnChange] = useSelectedOnChange(value, onChange) | ||
return ( | ||
<FormFieldset id={`fieldset-${name}`} {...props} > | ||
<FormLegend>{legend}</FormLegend> | ||
{Object.keys(catalog).map(key => ( | ||
<Radio | ||
key={key} | ||
value={key} | ||
isChecked={selectedOnChange === key} | ||
name={`service[${name}]`} | ||
onChange={setSelectedOnChange} | ||
label={catalog[key]} | ||
id={`service_method_${name}_${key}`} | ||
/> | ||
))} | ||
{children} | ||
</FormFieldset> | ||
) | ||
} | ||
|
||
export { | ||
RadioFieldset | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// @flow | ||
|
||
import * as React from 'react' | ||
import { useState } from 'react' | ||
import { FormGroup, Select, SelectOption } from '@patternfly/react-core' | ||
import type { FieldGroupProps, FieldCatalogProps } from 'Settings/types' | ||
|
||
type Props = FieldGroupProps & FieldCatalogProps | ||
|
||
const SelectGroup = ({ | ||
label, | ||
name, | ||
hint, | ||
value, | ||
catalog | ||
}: Props) => { | ||
const [ selectedValue, setSelectedValue ] = useState(value) | ||
const [ isExpanded, setIsExpanded ] = useState(false) | ||
const onSelect = (_e, selection) => { | ||
setIsExpanded(false) | ||
setSelectedValue(selection.key) | ||
} | ||
|
||
return ( | ||
<FormGroup label={label} fieldId={`service_proxy_attributes_${name}_select`} helperText={hint}> | ||
<input name={`service[proxy_attributes][${name}]`} type='hidden' value={selectedValue} /> | ||
<Select | ||
selections={catalog[selectedValue]} | ||
onToggle={setIsExpanded} | ||
onSelect={onSelect} | ||
isExpanded={isExpanded} | ||
id={`service_proxy_attributes_${name}_select`} | ||
> | ||
{Object.keys(catalog).map(key => ( | ||
didierofrivia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<SelectOption key={catalog[key]} value={{ key, toString: () => catalog[key] }} /> | ||
))} | ||
</Select> | ||
</FormGroup> | ||
) | ||
} | ||
|
||
export { | ||
SelectGroup | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// @flow | ||
|
||
import * as React from 'react' | ||
import { useState } from 'react' | ||
import { FormGroup, TextInput } from '@patternfly/react-core' | ||
import type { FieldGroupProps } from 'Settings/types' | ||
|
||
const TextInputGroup = ({ | ||
defaultValue, | ||
placeholder, | ||
label, | ||
name, | ||
hint, | ||
value, | ||
isDefaultValue = false, | ||
readOnly = false, | ||
inputType = 'text' | ||
}: FieldGroupProps) => { | ||
const [ inputValue, setInputValue ] = useState(value) | ||
const onChange = (value, _e) => setInputValue(value) | ||
didierofrivia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return ( | ||
<FormGroup label={label} fieldId={`service_proxy_attributes_${name}_input`} helperText={hint}> | ||
<TextInput | ||
id={`service_proxy_attributes_${name}_input`} | ||
name={`service[proxy_attributes][${name}]`} | ||
placeholder={placeholder} | ||
value={isDefaultValue ? defaultValue : inputValue} | ||
type={inputType} | ||
onChange={onChange} | ||
isReadOnly={readOnly} | ||
/> | ||
</FormGroup> | ||
) | ||
} | ||
|
||
export { | ||
TextInputGroup | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// @flow | ||
|
||
import * as React from 'react' | ||
import { FormFieldset, FormLegend } from 'Form' | ||
import { TextInputGroup, SelectGroup } from 'Settings/components/Common' | ||
import type { FieldGroupProps, FieldCatalogProps } from 'Settings/types' | ||
|
||
type Props = { | ||
type: FieldCatalogProps & FieldGroupProps, | ||
item: FieldGroupProps, | ||
legend: string | ||
} | ||
|
||
const TypeItemCombo = ({ type, item, legend }: Props) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what this component represent, "type item combo"? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was crafted to avoid repetition, didn't come up with a better name at the time. It represents a combination of a select + input. The input is a specification of selected value from the former. Any suggestions? |
||
return ( | ||
<FormFieldset id={`fieldset-${legend.replace(/\s+/g, '')}`}> | ||
<FormLegend>{legend}</FormLegend> | ||
<SelectGroup {...type} /> | ||
<TextInputGroup {...item} /> | ||
</FormFieldset> | ||
) | ||
} | ||
|
||
export { | ||
TypeItemCombo | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// @flow | ||
|
||
export * from 'Settings/components/Common/FormCollection' | ||
export * from 'Settings/components/Common/SelectGroup' | ||
export * from 'Settings/components/Common/TextInputGroup' | ||
export * from 'Settings/components/Common/RadioFieldset' | ||
export * from 'Settings/components/Common/TypeItemCombo' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// @flow | ||
|
||
import * as React from 'react' | ||
import { useState } from 'react' | ||
import { FormFieldset, FormLegend } from 'Form' | ||
import { FormCollection, TextInputGroup, RadioFieldset } from 'Settings/components/Common' | ||
import { AuthenticationSettingsFieldset } from 'Settings/components/AuthenticationSettingsFieldset' | ||
import type { SettingsProps as Props } from 'Settings/types' | ||
|
||
const SERVICE_MESH_INTEGRATION = 'service_mesh_istio' | ||
const PROXY_HOSTED_INTEGRATION = 'hosted' | ||
|
||
const Form = ({ | ||
isProxyCustomUrlActive, | ||
integrationMethod, | ||
authenticationMethod, | ||
proxyEndpoints, | ||
authenticationSettings, | ||
credentialsLocation, | ||
security, | ||
gatewayResponse | ||
}: Props) => { | ||
const [ selectedIntegrationMethod, setSelectedIntegrationMethod ] = useState(integrationMethod.value) | ||
const [ selectedAuthenticationMethod, setSelectedAuthenticationMethod ] = useState(authenticationMethod.value) | ||
const onChange = (setState) => (_checked, e) => setState(e.currentTarget.value) | ||
const isServiceMesh = selectedIntegrationMethod === SERVICE_MESH_INTEGRATION | ||
const isProxyHosted = selectedIntegrationMethod === PROXY_HOSTED_INTEGRATION | ||
const isProxyUrlsReadOnly = !isProxyCustomUrlActive && isProxyHosted | ||
const customProxyEndpoints = proxyEndpoints.map(endpoint => | ||
({ ...endpoint, readOnly: isProxyUrlsReadOnly, isDefaultValue: isProxyUrlsReadOnly })) | ||
|
||
return ( | ||
<React.Fragment> | ||
<RadioFieldset {...integrationMethod} onChange={onChange(setSelectedIntegrationMethod)} value={selectedIntegrationMethod} legend='Integration' /> | ||
{ !isServiceMesh && <FormCollection collection={customProxyEndpoints} ItemComponent={TextInputGroup} legend='API gateway' /> } | ||
<RadioFieldset {...authenticationMethod} onChange={onChange(setSelectedAuthenticationMethod)} value={selectedAuthenticationMethod} legend='Authentication' /> | ||
<AuthenticationSettingsFieldset | ||
isServiceMesh={isServiceMesh} | ||
authenticationMethod={selectedAuthenticationMethod} | ||
{...authenticationSettings} | ||
/> | ||
{ !isServiceMesh && <React.Fragment> | ||
<RadioFieldset {...credentialsLocation} legend='Credentials Location' /> | ||
<FormCollection collection={security} ItemComponent={TextInputGroup} legend='Security' /> | ||
<FormFieldset id='fieldset-GatewayResponse'> | ||
<FormLegend>Gateway Response</FormLegend> | ||
{gatewayResponse.map(settings => ( | ||
<FormCollection key={settings.legend} collection={settings.collection} ItemComponent={TextInputGroup} legend={settings.legend} /> | ||
))} | ||
</FormFieldset> | ||
</React.Fragment> } | ||
</React.Fragment> | ||
) | ||
} | ||
|
||
export { | ||
Form | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According with lines 37:40, is it possible to render an empty FormFieldSet? Namely if isServiceMesh is true and the rest false.