1
0
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:
olav 2022-04-20 11:47:17 +02:00 committed by GitHub
parent cb8add5c30
commit 9bb0ce8cad
17 changed files with 72 additions and 94 deletions

View File

@ -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"

View File

@ -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>

View File

@ -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>

View File

@ -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}

View File

@ -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}

View File

@ -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}
/>

View File

@ -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 (

View File

@ -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

View File

@ -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}
/>

View File

@ -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 => ({

View File

@ -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}

View File

@ -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()}

View File

@ -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'

View File

@ -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>

View File

@ -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>

View File

@ -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}
/>

View File

@ -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,
};