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,
|
Button,
|
||||||
capitalize,
|
capitalize,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
|
Chip,
|
||||||
styled,
|
styled,
|
||||||
TextField,
|
TextField,
|
||||||
Tooltip,
|
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 {
|
interface IAccessOption {
|
||||||
id: number;
|
id: number;
|
||||||
entity: IUser | IGroup;
|
entity: IUser | IGroup;
|
||||||
@ -272,7 +285,7 @@ export const ProjectAccessAssign = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderOption = (
|
const renderOption = (
|
||||||
props: React.HTMLAttributes<HTMLLIElement>,
|
{ key, ...props }: React.HTMLAttributes<HTMLLIElement> & { key?: any },
|
||||||
option: IAccessOption,
|
option: IAccessOption,
|
||||||
selected: boolean,
|
selected: boolean,
|
||||||
) => {
|
) => {
|
||||||
@ -283,9 +296,9 @@ export const ProjectAccessAssign = ({
|
|||||||
optionUser = option.entity as IUser;
|
optionUser = option.entity as IUser;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
<li key={key} {...props}>
|
||||||
<Tooltip title={createRootGroupWarning(optionGroup)}>
|
<Tooltip title={createRootGroupWarning(optionGroup)}>
|
||||||
<span>
|
<>
|
||||||
<li {...props}>
|
|
||||||
<Checkbox
|
<Checkbox
|
||||||
icon={<CheckBoxOutlineBlankIcon fontSize='small' />}
|
icon={<CheckBoxOutlineBlankIcon fontSize='small' />}
|
||||||
checkedIcon={<CheckBoxIcon fontSize='small' />}
|
checkedIcon={<CheckBoxIcon fontSize='small' />}
|
||||||
@ -319,9 +332,9 @@ export const ProjectAccessAssign = ({
|
|||||||
</StyledUserOption>
|
</StyledUserOption>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</li>
|
</>
|
||||||
</span>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
</li>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -340,6 +353,8 @@ export const ProjectAccessAssign = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const autocompleteSize = 'small';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarModal
|
<SidebarModal
|
||||||
open
|
open
|
||||||
@ -365,7 +380,7 @@ export const ProjectAccessAssign = ({
|
|||||||
<StyledAutocompleteWrapper>
|
<StyledAutocompleteWrapper>
|
||||||
<AutocompleteVirtual
|
<AutocompleteVirtual
|
||||||
data-testid={PA_USERS_GROUPS_ID}
|
data-testid={PA_USERS_GROUPS_ID}
|
||||||
size='small'
|
size={autocompleteSize}
|
||||||
multiple
|
multiple
|
||||||
openOnFocus
|
openOnFocus
|
||||||
limitTags={10}
|
limitTags={10}
|
||||||
@ -396,24 +411,19 @@ export const ProjectAccessAssign = ({
|
|||||||
renderOption={(props, option, { selected }) =>
|
renderOption={(props, option, { selected }) =>
|
||||||
renderOption(props, option, selected)
|
renderOption(props, option, selected)
|
||||||
}
|
}
|
||||||
getOptionLabel={(option: IAccessOption) => {
|
getOptionLabel={getOptionLabel}
|
||||||
if (
|
renderTags={(tagValue, getTagProps) =>
|
||||||
option.type === ENTITY_TYPE.USER ||
|
tagValue.map((option, index) => {
|
||||||
option.type ===
|
|
||||||
ENTITY_TYPE.SERVICE_ACCOUNT
|
|
||||||
) {
|
|
||||||
const optionUser =
|
|
||||||
option.entity as IUser;
|
|
||||||
return (
|
return (
|
||||||
optionUser.email ||
|
<Chip
|
||||||
optionUser.name ||
|
{...getTagProps({ index })}
|
||||||
optionUser.username ||
|
size={autocompleteSize}
|
||||||
''
|
key={`${option.type}:${option.id}`}
|
||||||
|
label={getOptionLabel(option)}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
})
|
||||||
return option.entity.name;
|
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
filterOptions={(options, { inputValue }) =>
|
filterOptions={(options, { inputValue }) =>
|
||||||
options.filter((option: IAccessOption) => {
|
options.filter((option: IAccessOption) => {
|
||||||
if (
|
if (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user