mirror of
https://github.com/Unleash/unleash.git
synced 2025-12-09 20:04:11 +01:00
fix: don't spread props + nest li correctly (#10923)
Fixes a few errors appearing on the "assign user/group" on the project settings pages. Namely: - spreading "key" into props in two places (option list and selected chips) - incorrect HTML nesting ([`li`'s only permitted parents are `ul`, `ol`, and `menu`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/li#technical_summary)) - missing key in the list (caused by nesting the `li`) The renderOption type update is based on a [fix that was added in a more recent version of mui](https://github.com/mui/material-ui/pull/42689/files). For some reason, the default tag rendering spreads the key in somehow, so I've had to add a manual `renderTags` prop, and as such extracted the `getOptionLabel` function. If you know a better way of sorting out the fact that the `key` prop is spread into the default MUI chips, I'd be very happy to implement that instead.
This commit is contained in:
parent
7215e6bdfb
commit
2f25f5fd8a
@ -4,6 +4,7 @@ import {
|
||||
Button,
|
||||
capitalize,
|
||||
Checkbox,
|
||||
Chip,
|
||||
styled,
|
||||
TextField,
|
||||
Tooltip,
|
||||
@ -86,6 +87,18 @@ const StyledUserOption = styled('div')(({ theme }) => ({
|
||||
},
|
||||
}));
|
||||
|
||||
const getOptionLabel = (option: IAccessOption) => {
|
||||
if (
|
||||
option.type === ENTITY_TYPE.USER ||
|
||||
option.type === ENTITY_TYPE.SERVICE_ACCOUNT
|
||||
) {
|
||||
const optionUser = option.entity as IUser;
|
||||
return optionUser.email || optionUser.name || optionUser.username || '';
|
||||
} else {
|
||||
return option.entity.name;
|
||||
}
|
||||
};
|
||||
|
||||
interface IAccessOption {
|
||||
id: number;
|
||||
entity: IUser | IGroup;
|
||||
@ -272,7 +285,7 @@ export const ProjectAccessAssign = ({
|
||||
};
|
||||
|
||||
const renderOption = (
|
||||
props: React.HTMLAttributes<HTMLLIElement>,
|
||||
{ key, ...props }: React.HTMLAttributes<HTMLLIElement> & { key?: any },
|
||||
option: IAccessOption,
|
||||
selected: boolean,
|
||||
) => {
|
||||
@ -283,9 +296,9 @@ export const ProjectAccessAssign = ({
|
||||
optionUser = option.entity as IUser;
|
||||
}
|
||||
return (
|
||||
<Tooltip title={createRootGroupWarning(optionGroup)}>
|
||||
<span>
|
||||
<li {...props}>
|
||||
<li key={key} {...props}>
|
||||
<Tooltip title={createRootGroupWarning(optionGroup)}>
|
||||
<>
|
||||
<Checkbox
|
||||
icon={<CheckBoxOutlineBlankIcon fontSize='small' />}
|
||||
checkedIcon={<CheckBoxIcon fontSize='small' />}
|
||||
@ -319,9 +332,9 @@ export const ProjectAccessAssign = ({
|
||||
</StyledUserOption>
|
||||
}
|
||||
/>
|
||||
</li>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</>
|
||||
</Tooltip>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
|
||||
@ -340,6 +353,8 @@ export const ProjectAccessAssign = ({
|
||||
);
|
||||
}
|
||||
|
||||
const autocompleteSize = 'small';
|
||||
|
||||
return (
|
||||
<SidebarModal
|
||||
open
|
||||
@ -365,7 +380,7 @@ export const ProjectAccessAssign = ({
|
||||
<StyledAutocompleteWrapper>
|
||||
<AutocompleteVirtual
|
||||
data-testid={PA_USERS_GROUPS_ID}
|
||||
size='small'
|
||||
size={autocompleteSize}
|
||||
multiple
|
||||
openOnFocus
|
||||
limitTags={10}
|
||||
@ -396,24 +411,19 @@ export const ProjectAccessAssign = ({
|
||||
renderOption={(props, option, { selected }) =>
|
||||
renderOption(props, option, selected)
|
||||
}
|
||||
getOptionLabel={(option: IAccessOption) => {
|
||||
if (
|
||||
option.type === ENTITY_TYPE.USER ||
|
||||
option.type ===
|
||||
ENTITY_TYPE.SERVICE_ACCOUNT
|
||||
) {
|
||||
const optionUser =
|
||||
option.entity as IUser;
|
||||
getOptionLabel={getOptionLabel}
|
||||
renderTags={(tagValue, getTagProps) =>
|
||||
tagValue.map((option, index) => {
|
||||
return (
|
||||
optionUser.email ||
|
||||
optionUser.name ||
|
||||
optionUser.username ||
|
||||
''
|
||||
<Chip
|
||||
{...getTagProps({ index })}
|
||||
size={autocompleteSize}
|
||||
key={`${option.type}:${option.id}`}
|
||||
label={getOptionLabel(option)}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
return option.entity.name;
|
||||
}
|
||||
}}
|
||||
})
|
||||
}
|
||||
filterOptions={(options, { inputValue }) =>
|
||||
options.filter((option: IAccessOption) => {
|
||||
if (
|
||||
|
||||
Loading…
Reference in New Issue
Block a user