1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-03-23 00:16:25 +01:00

fix: add forwardRef to ProjectSelect component (#6674)

Make the tooltip for project selection in the playground work properly
again. Right now, it doesn't work due to an error in react refs.

Because we wrap this in a tooltip in the Playground, we need to forward
the ref to the underlying component.

This follows the steps outlined in
https://mui.com/material-ui/guides/composition/#caveat-with-refs
This commit is contained in:
Thomas Heartman 2024-03-25 10:23:22 +01:00 committed by GitHub
parent 8a9d013545
commit 6025ad0f0d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,4 +1,10 @@
import type { ComponentProps, Dispatch, SetStateAction, VFC } from 'react';
import {
forwardRef,
type ComponentProps,
type Dispatch,
type SetStateAction,
type VFC,
} from 'react';
import { Autocomplete, type SxProps, TextField } from '@mui/material';
import { renderOption } from 'component/playground/Playground/PlaygroundForm/renderOption';
import useProjects from 'hooks/api/getters/useProjects/useProjects';
@ -30,85 +36,87 @@ function findAllIndexes(arr: string[], name: string): number[] {
return indexes;
}
export const ProjectSelect: VFC<IProjectSelectProps> = ({
selectedProjects,
onChange,
dataTestId,
sx,
disabled,
}) => {
const { projects: availableProjects } = useProjects();
const projectNames = availableProjects.map(({ name }) => name);
const projectsOptions = [
allOption,
...availableProjects.map(({ name, id }) => {
const indexes = findAllIndexes(projectNames, name);
const isDuplicate = indexes.length > 1;
return {
label: isDuplicate ? `${name} - (${id})` : name,
id,
};
}),
];
const isAllProjects =
selectedProjects &&
(selectedProjects.length === 0 ||
(selectedProjects.length === 1 && selectedProjects[0] === '*'));
const onProjectsChange: ComponentProps<typeof Autocomplete>['onChange'] = (
event,
value,
reason,
export const ProjectSelect: VFC<IProjectSelectProps> = forwardRef(
(
{ selectedProjects, onChange, dataTestId, sx, disabled, ...props },
ref,
) => {
const newProjects = value as IOption | IOption[];
if (reason === 'clear' || newProjects === null) {
return onChange([allOption.id]);
}
if (Array.isArray(newProjects)) {
if (newProjects.length === 0) {
const { projects: availableProjects } = useProjects();
const projectNames = availableProjects.map(({ name }) => name);
const projectsOptions = [
allOption,
...availableProjects.map(({ name, id }) => {
const indexes = findAllIndexes(projectNames, name);
const isDuplicate = indexes.length > 1;
return {
label: isDuplicate ? `${name} - (${id})` : name,
id,
};
}),
];
const isAllProjects =
selectedProjects &&
(selectedProjects.length === 0 ||
(selectedProjects.length === 1 && selectedProjects[0] === '*'));
const onProjectsChange: ComponentProps<
typeof Autocomplete
>['onChange'] = (event, value, reason) => {
const newProjects = value as IOption | IOption[];
if (reason === 'clear' || newProjects === null) {
return onChange([allOption.id]);
}
if (
newProjects.find(({ id }) => id === allOption.id) !== undefined
) {
if (Array.isArray(newProjects)) {
if (newProjects.length === 0) {
return onChange([allOption.id]);
}
if (
newProjects.find(({ id }) => id === allOption.id) !==
undefined
) {
return onChange([allOption.id]);
}
return onChange(newProjects.map(({ id }) => id));
}
if (newProjects.id === allOption.id) {
return onChange([allOption.id]);
}
return onChange(newProjects.map(({ id }) => id));
}
if (newProjects.id === allOption.id) {
return onChange([allOption.id]);
}
return onChange([newProjects.id]);
};
return onChange([newProjects.id]);
};
return (
<Autocomplete
disablePortal
id='projects'
limitTags={3}
multiple={!isAllProjects}
options={projectsOptions}
sx={sx}
renderInput={(params) => <TextField {...params} label='Projects' />}
renderOption={renderOption}
getOptionLabel={({ label }) => label}
disableCloseOnSelect
size='small'
disabled={disabled}
value={
isAllProjects
? allOption
: projectsOptions.filter(({ id }) =>
selectedProjects.includes(id),
)
}
onChange={onProjectsChange}
data-testid={dataTestId ? dataTestId : 'PROJECT_SELECT'}
/>
);
};
return (
<Autocomplete
{...props}
ref={ref}
disablePortal
id='projects'
limitTags={3}
multiple={!isAllProjects}
options={projectsOptions}
sx={sx}
renderInput={(params) => (
<TextField {...params} label='Projects' />
)}
renderOption={renderOption}
getOptionLabel={({ label }) => label}
disableCloseOnSelect
size='small'
disabled={disabled}
value={
isAllProjects
? allOption
: projectsOptions.filter(({ id }) =>
selectedProjects.includes(id),
)
}
onChange={onProjectsChange}
data-testid={dataTestId ? dataTestId : 'PROJECT_SELECT'}
/>
);
},
);