mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-09 00:18:00 +01:00
refactor: improve GeneralSelect prop types (#883)
* refactor: improve GeneralSelect prop types * refactor: Remove unused propTypes
This commit is contained in:
parent
cb8add5c30
commit
9bb0ce8cad
@ -87,7 +87,7 @@ const ApiTokenForm: React.FC<IApiTokenFormProps> = ({
|
||||
<GeneralSelect
|
||||
options={selectableTypes}
|
||||
value={type}
|
||||
onChange={e => setTokenType(e.target.value as string)}
|
||||
onChange={setTokenType}
|
||||
label="Token Type"
|
||||
id="api_key_type"
|
||||
name="type"
|
||||
@ -113,7 +113,7 @@ const ApiTokenForm: React.FC<IApiTokenFormProps> = ({
|
||||
disabled={type === TYPE_ADMIN}
|
||||
options={selectableEnvs}
|
||||
value={environment}
|
||||
onChange={e => setEnvironment(e.target.value as string)}
|
||||
onChange={setEnvironment}
|
||||
label="Environment"
|
||||
id="api_key_environment"
|
||||
name="environment"
|
||||
|
@ -22,12 +22,12 @@ export const ApplicationUpdate = ({ application }: IApplicationUpdateProps) => {
|
||||
const { setToastData, setToastApiError } = useToast();
|
||||
const commonStyles = useCommonStyles();
|
||||
|
||||
const handleChange = async (
|
||||
evt: ChangeEvent<{ name?: string | undefined; value: unknown }>,
|
||||
const onChange = async (
|
||||
field: string,
|
||||
value: string
|
||||
value: string,
|
||||
event?: ChangeEvent
|
||||
) => {
|
||||
evt.preventDefault();
|
||||
event?.preventDefault();
|
||||
try {
|
||||
await storeApplicationMetaData(appName, field, value);
|
||||
refetchApplication();
|
||||
@ -51,9 +51,7 @@ export const ApplicationUpdate = ({ application }: IApplicationUpdateProps) => {
|
||||
label="Icon"
|
||||
options={icons.map(v => ({ key: v, label: v }))}
|
||||
value={icon || 'apps'}
|
||||
onChange={e =>
|
||||
handleChange(e, 'icon', e.target.value as string)
|
||||
}
|
||||
onChange={key => onChange('icon', key)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
@ -65,7 +63,7 @@ export const ApplicationUpdate = ({ application }: IApplicationUpdateProps) => {
|
||||
type="url"
|
||||
variant="outlined"
|
||||
size="small"
|
||||
onBlur={e => handleChange(e, 'url', localUrl)}
|
||||
onBlur={e => onChange('url', localUrl, e)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
@ -77,7 +75,7 @@ export const ApplicationUpdate = ({ application }: IApplicationUpdateProps) => {
|
||||
rows={2}
|
||||
onChange={e => setLocalDescription(e.target.value)}
|
||||
onBlur={e =>
|
||||
handleChange(e, 'description', localDescription)
|
||||
onChange('description', localDescription, e)
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
|
@ -94,7 +94,7 @@ export const ConstraintAccordionEditHeader = ({
|
||||
autoFocus
|
||||
options={constraintNameOptions}
|
||||
value={contextName || ''}
|
||||
onChange={e => setContextName(String(e.target.value))}
|
||||
onChange={setContextName}
|
||||
className={styles.headerSelect}
|
||||
/>
|
||||
</div>
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
} from '@material-ui/core';
|
||||
import { SELECT_ITEM_ID } from 'utils/testIds';
|
||||
import { KeyboardArrowDownOutlined } from '@material-ui/icons';
|
||||
import { SelectInputProps } from '@material-ui/core/Select/SelectInput';
|
||||
|
||||
export interface ISelectOption {
|
||||
key: string;
|
||||
@ -16,24 +17,19 @@ export interface ISelectOption {
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export interface ISelectMenuProps extends SelectProps {
|
||||
export interface IGeneralSelectProps extends Omit<SelectProps, 'onChange'> {
|
||||
name?: string;
|
||||
value?: string;
|
||||
label?: string;
|
||||
options: ISelectOption[];
|
||||
onChange?: OnGeneralSelectChange;
|
||||
onChange: (key: string) => void;
|
||||
disabled?: boolean;
|
||||
fullWidth?: boolean;
|
||||
classes?: any;
|
||||
defaultValue?: string;
|
||||
}
|
||||
|
||||
export type OnGeneralSelectChange = (
|
||||
event: React.ChangeEvent<{ name?: string; value: unknown }>,
|
||||
child: React.ReactNode
|
||||
) => void;
|
||||
|
||||
const GeneralSelect: React.FC<ISelectMenuProps> = ({
|
||||
const GeneralSelect: React.FC<IGeneralSelectProps> = ({
|
||||
name,
|
||||
value = '',
|
||||
label = '',
|
||||
@ -59,6 +55,11 @@ const GeneralSelect: React.FC<ISelectMenuProps> = ({
|
||||
</MenuItem>
|
||||
));
|
||||
|
||||
const onSelectChange: SelectInputProps['onChange'] = event => {
|
||||
event.preventDefault();
|
||||
onChange(String(event.target.value));
|
||||
};
|
||||
|
||||
return (
|
||||
<FormControl
|
||||
variant="outlined"
|
||||
@ -70,7 +71,7 @@ const GeneralSelect: React.FC<ISelectMenuProps> = ({
|
||||
<Select
|
||||
name={name}
|
||||
disabled={disabled}
|
||||
onChange={onChange}
|
||||
onChange={onSelectChange}
|
||||
className={className}
|
||||
label={label}
|
||||
id={id}
|
||||
|
@ -1,10 +1,14 @@
|
||||
import React from 'react';
|
||||
import GeneralSelect from '../GeneralSelect/GeneralSelect';
|
||||
import GeneralSelect, {
|
||||
IGeneralSelectProps,
|
||||
} from '../GeneralSelect/GeneralSelect';
|
||||
import useTagTypes from 'hooks/api/getters/useTagTypes/useTagTypes';
|
||||
|
||||
interface ITagSelect extends React.SelectHTMLAttributes<HTMLSelectElement> {
|
||||
interface ITagSelect {
|
||||
name: string;
|
||||
value: string;
|
||||
onChange: (val: any) => void;
|
||||
onChange: IGeneralSelectProps['onChange'];
|
||||
autoFocus?: boolean;
|
||||
}
|
||||
|
||||
const TagSelect = ({ value, onChange, ...rest }: ITagSelect) => {
|
||||
@ -18,10 +22,8 @@ const TagSelect = ({ value, onChange, ...rest }: ITagSelect) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* @ts-expect-error */}
|
||||
<GeneralSelect
|
||||
label="Tag type"
|
||||
name="tag-select"
|
||||
id="tag-select"
|
||||
options={options}
|
||||
value={value}
|
||||
|
@ -92,8 +92,7 @@ const FeatureForm: React.FC<IFeatureToggleForm> = ({
|
||||
</p>
|
||||
<FeatureTypeSelect
|
||||
value={type}
|
||||
// @ts-expect-error
|
||||
onChange={(e: React.ChangeEvent) => setType(e.target.value)}
|
||||
onChange={setType}
|
||||
label={'Toggle type'}
|
||||
id="feature-type-select"
|
||||
editable
|
||||
@ -114,15 +113,12 @@ const FeatureForm: React.FC<IFeatureToggleForm> = ({
|
||||
/>
|
||||
<FeatureProjectSelect
|
||||
value={project}
|
||||
onChange={e => {
|
||||
setProject(e.target.value);
|
||||
history.replace(
|
||||
`/projects/${e.target.value}/create-toggle`
|
||||
);
|
||||
onChange={projectId => {
|
||||
setProject(projectId);
|
||||
history.replace(`/projects/${projectId}/create-toggle`);
|
||||
}}
|
||||
enabled={editable}
|
||||
filter={projectFilterGenerator(permissions, CREATE_FEATURE)}
|
||||
// @ts-expect-error
|
||||
IconComponent={KeyboardArrowDownOutlined}
|
||||
className={styles.selectInput}
|
||||
/>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import GeneralSelect, {
|
||||
OnGeneralSelectChange,
|
||||
IGeneralSelectProps,
|
||||
} from 'component/common/GeneralSelect/GeneralSelect';
|
||||
|
||||
interface IFeatureMetricsHoursProps {
|
||||
@ -13,8 +13,8 @@ export const FeatureMetricsHours = ({
|
||||
hoursBack,
|
||||
setHoursBack,
|
||||
}: IFeatureMetricsHoursProps) => {
|
||||
const onChange: OnGeneralSelectChange = event => {
|
||||
setHoursBack(parseFeatureMetricsHour(event.target.value));
|
||||
const onChange: IGeneralSelectProps['onChange'] = key => {
|
||||
setHoursBack(parseFeatureMetricsHour(key));
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -94,7 +94,7 @@ const AddTagDialog = ({ open, setOpen }: IAddTagDialogProps) => {
|
||||
autoFocus
|
||||
name="type"
|
||||
value={tag.type}
|
||||
onChange={e => setValue('type', e.target.value)}
|
||||
onChange={type => setValue('type', type)}
|
||||
/>
|
||||
<br />
|
||||
<Input
|
||||
|
@ -65,8 +65,7 @@ const FeatureSettingsMetadata = () => {
|
||||
<FeatureTypeSelect
|
||||
value={type}
|
||||
id="feature-type-select"
|
||||
// @ts-expect-error
|
||||
onChange={e => setType(e.target.value)}
|
||||
onChange={setType}
|
||||
label="Feature type"
|
||||
editable={editable}
|
||||
/>
|
||||
|
@ -1,21 +1,23 @@
|
||||
import useFeatureTypes from 'hooks/api/getters/useFeatureTypes/useFeatureTypes';
|
||||
import GeneralSelect, {
|
||||
ISelectOption,
|
||||
IGeneralSelectProps,
|
||||
} from 'component/common/GeneralSelect/GeneralSelect';
|
||||
|
||||
interface IFeatureTypeSelectProps
|
||||
extends Omit<IGeneralSelectProps, 'options' | 'value'> {
|
||||
value: string;
|
||||
editable: boolean;
|
||||
}
|
||||
|
||||
const FeatureTypeSelect = ({
|
||||
// @ts-expect-error
|
||||
editable,
|
||||
// @ts-expect-error
|
||||
value,
|
||||
// @ts-expect-error
|
||||
id,
|
||||
// @ts-expect-error
|
||||
label,
|
||||
// @ts-expect-error
|
||||
onChange,
|
||||
...rest
|
||||
}) => {
|
||||
}: IFeatureTypeSelectProps) => {
|
||||
const { featureTypes } = useFeatureTypes();
|
||||
|
||||
const options: ISelectOption[] = featureTypes.map(t => ({
|
||||
|
@ -1,11 +1,15 @@
|
||||
import useProjects from 'hooks/api/getters/useProjects/useProjects';
|
||||
import { IProject } from 'interfaces/project';
|
||||
import GeneralSelect from 'component/common/GeneralSelect/GeneralSelect';
|
||||
import { IProjectCard } from 'interfaces/project';
|
||||
import GeneralSelect, {
|
||||
ISelectOption,
|
||||
IGeneralSelectProps,
|
||||
} from 'component/common/GeneralSelect/GeneralSelect';
|
||||
import React from 'react';
|
||||
|
||||
interface IFeatureProjectSelect {
|
||||
interface IFeatureProjectSelectProps
|
||||
extends Omit<IGeneralSelectProps, 'options'> {
|
||||
enabled: boolean;
|
||||
value: string;
|
||||
onChange: (e: any) => void;
|
||||
filter: (project: string) => void;
|
||||
}
|
||||
|
||||
@ -15,14 +19,14 @@ const FeatureProjectSelect = ({
|
||||
onChange,
|
||||
filter,
|
||||
...rest
|
||||
}: IFeatureProjectSelect) => {
|
||||
}: IFeatureProjectSelectProps) => {
|
||||
const { projects } = useProjects();
|
||||
|
||||
if (!enabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const formatOption = (project: IProject) => {
|
||||
const formatOption = (project: IProjectCard) => {
|
||||
return {
|
||||
key: project.id,
|
||||
label: project.name,
|
||||
@ -30,28 +34,23 @@ const FeatureProjectSelect = ({
|
||||
};
|
||||
};
|
||||
|
||||
let options;
|
||||
let options: ISelectOption[];
|
||||
|
||||
if (filter) {
|
||||
options = projects
|
||||
.filter(project => {
|
||||
return filter(project.id);
|
||||
})
|
||||
// @ts-expect-error
|
||||
.filter(project => filter(project.id))
|
||||
.map(formatOption);
|
||||
} else {
|
||||
// @ts-expect-error
|
||||
options = projects.map(formatOption);
|
||||
}
|
||||
|
||||
if (value && !options.find(o => o.key === value)) {
|
||||
// @ts-expect-error
|
||||
options.push({ key: value, label: value });
|
||||
}
|
||||
|
||||
return (
|
||||
<GeneralSelect
|
||||
label="Project"
|
||||
// @ts-expect-error
|
||||
options={options}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
|
@ -92,8 +92,7 @@ const FeatureSettingsProject = () => {
|
||||
<>
|
||||
<FeatureProjectSelect
|
||||
value={project}
|
||||
onChange={e => setProject(e.target.value)}
|
||||
// @ts-expect-error
|
||||
onChange={setProject}
|
||||
label="Project"
|
||||
enabled={editable}
|
||||
filter={filterProjects()}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useState, ChangeEvent } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import {
|
||||
Button,
|
||||
FormControl,
|
||||
@ -189,14 +189,9 @@ export const AddVariant = ({
|
||||
}
|
||||
};
|
||||
|
||||
const onPayload = (e: ChangeEvent<{ name?: string; value: unknown }>) => {
|
||||
e.preventDefault();
|
||||
const onPayload = (name: string) => (value: string) => {
|
||||
setError({ payload: '' });
|
||||
setPayload({
|
||||
...payload,
|
||||
// @ts-expect-error
|
||||
[e.target.name]: e.target.value,
|
||||
});
|
||||
setPayload({ ...payload, [name]: value });
|
||||
};
|
||||
|
||||
const onCancel = (e: React.SyntheticEvent) => {
|
||||
@ -206,13 +201,12 @@ export const AddVariant = ({
|
||||
};
|
||||
|
||||
const updateOverrideType =
|
||||
(index: number) => (e: ChangeEvent<HTMLInputElement>) => {
|
||||
e.preventDefault();
|
||||
(index: number, contextName: string) => (value: string) => {
|
||||
setOverrides(
|
||||
overrides.map((o, i) => {
|
||||
if (i === index) {
|
||||
// @ts-expect-error
|
||||
o[e.target.name] = e.target.value;
|
||||
o[contextName] = value;
|
||||
}
|
||||
|
||||
return o;
|
||||
@ -367,7 +361,7 @@ export const AddVariant = ({
|
||||
className={styles.select}
|
||||
value={payload.type}
|
||||
options={payloadOptions}
|
||||
onChange={onPayload}
|
||||
onChange={onPayload('type')}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item md={8} sm={8} xs={6}>
|
||||
@ -377,7 +371,7 @@ export const AddVariant = ({
|
||||
name="value"
|
||||
className={commonStyles.fullWidth}
|
||||
value={payload.value}
|
||||
onChange={onPayload}
|
||||
onChange={e => onPayload('value')(e.target.value)}
|
||||
data-testid={'VARIANT_PAYLOAD_VALUE'}
|
||||
placeholder={
|
||||
payload.type === 'json'
|
||||
|
@ -54,7 +54,7 @@ export const OverrideConfig = ({
|
||||
classes={{
|
||||
root: classnames(commonStyles.fullWidth),
|
||||
}}
|
||||
onChange={updateOverrideType(i)}
|
||||
onChange={updateOverrideType(i, o.contextName)}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid md={7} sm={7} xs={6} item>
|
||||
|
@ -90,9 +90,7 @@ const StrategyConstraintInputField = ({
|
||||
label="Context Field"
|
||||
options={constraintContextNames}
|
||||
value={constraint.contextName || ''}
|
||||
onChange={evt =>
|
||||
updateConstraint(evt.target.value, 'contextName')
|
||||
}
|
||||
onChange={value => updateConstraint(value, 'contextName')}
|
||||
className={styles.contextField}
|
||||
/>
|
||||
</td>
|
||||
@ -102,9 +100,7 @@ const StrategyConstraintInputField = ({
|
||||
label="Operator"
|
||||
options={constraintOperators}
|
||||
value={constraint.operator}
|
||||
onChange={evt =>
|
||||
updateConstraint(evt.target.value, 'operator')
|
||||
}
|
||||
onChange={value => updateConstraint(value, 'operator')}
|
||||
className={styles.operator}
|
||||
/>
|
||||
</td>
|
||||
|
@ -57,10 +57,9 @@ export const StrategyParameter = ({
|
||||
errors,
|
||||
}: IStrategyParameterProps) => {
|
||||
const styles = useStyles();
|
||||
const handleTypeChange = (
|
||||
event: React.ChangeEvent<{ name?: string; value: unknown }>
|
||||
) => {
|
||||
set({ type: event.target.value });
|
||||
|
||||
const onTypeChange = (type: string) => {
|
||||
set({ type });
|
||||
};
|
||||
|
||||
const renderParamTypeDescription = () => {
|
||||
@ -102,7 +101,7 @@ export const StrategyParameter = ({
|
||||
name="type"
|
||||
options={paramTypesOptions}
|
||||
value={input.type}
|
||||
onChange={handleTypeChange}
|
||||
onChange={onTypeChange}
|
||||
id={`prop-type-${index}-select`}
|
||||
className={styles.input}
|
||||
/>
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { useContext, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Link, useHistory } from 'react-router-dom';
|
||||
import {
|
||||
Button,
|
||||
@ -161,9 +160,3 @@ export const TagTypeList = () => {
|
||||
</PageContent>
|
||||
);
|
||||
};
|
||||
|
||||
TagTypeList.propTypes = {
|
||||
tagTypes: PropTypes.array.isRequired,
|
||||
fetchTagTypes: PropTypes.func.isRequired,
|
||||
removeTagType: PropTypes.func.isRequired,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user