2022-12-20 18:05:37 +08:00
|
|
|
import React from 'react';
|
|
|
|
|
|
|
|
|
|
import { Role } from 'app/types';
|
|
|
|
|
|
|
|
|
|
import { RoleMenuGroupOption } from './RoleMenuGroupOption';
|
|
|
|
|
import { RoleMenuOption } from './RoleMenuOption';
|
|
|
|
|
import { RolePickerSubMenu } from './RolePickerSubMenu';
|
|
|
|
|
import { isNotDelegatable } from './utils';
|
|
|
|
|
|
|
|
|
|
interface RoleMenuGroupsSectionProps {
|
|
|
|
|
roles: Role[];
|
|
|
|
|
renderedName: string;
|
|
|
|
|
menuSectionStyle: string;
|
|
|
|
|
groupHeaderStyle: string;
|
|
|
|
|
optionBodyStyle: string;
|
|
|
|
|
showGroups?: boolean;
|
|
|
|
|
optionGroups: Array<{
|
|
|
|
|
name: string;
|
|
|
|
|
options: Role[];
|
|
|
|
|
value: string;
|
|
|
|
|
}>;
|
|
|
|
|
onChange: (value: string) => void;
|
|
|
|
|
onOpenSubMenuRMGS: (value: string) => void;
|
|
|
|
|
onCloseSubMenu?: (value: string) => void;
|
|
|
|
|
groupSelected: (group: string) => boolean;
|
|
|
|
|
groupPartiallySelected: (group: string) => boolean;
|
|
|
|
|
disabled?: boolean;
|
|
|
|
|
subMenuNode?: HTMLDivElement;
|
|
|
|
|
showSubMenu: boolean;
|
|
|
|
|
openedMenuGroup: string;
|
|
|
|
|
subMenuOptions: Role[];
|
|
|
|
|
selectedOptions: Role[];
|
|
|
|
|
onChangeSubMenu: (option: Role) => void;
|
|
|
|
|
onClearSubMenu: () => void;
|
|
|
|
|
showOnLeftSubMenu: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const RoleMenuGroupsSection = React.forwardRef<HTMLDivElement, RoleMenuGroupsSectionProps>(
|
|
|
|
|
(
|
|
|
|
|
{
|
|
|
|
|
roles,
|
|
|
|
|
renderedName,
|
|
|
|
|
menuSectionStyle,
|
|
|
|
|
groupHeaderStyle,
|
|
|
|
|
optionBodyStyle,
|
|
|
|
|
showGroups,
|
|
|
|
|
optionGroups,
|
|
|
|
|
onChange,
|
|
|
|
|
groupSelected,
|
|
|
|
|
groupPartiallySelected,
|
|
|
|
|
onOpenSubMenuRMGS,
|
|
|
|
|
onCloseSubMenu,
|
|
|
|
|
subMenuNode,
|
|
|
|
|
showSubMenu,
|
|
|
|
|
openedMenuGroup,
|
|
|
|
|
subMenuOptions,
|
|
|
|
|
selectedOptions,
|
|
|
|
|
onChangeSubMenu,
|
|
|
|
|
onClearSubMenu,
|
|
|
|
|
showOnLeftSubMenu,
|
|
|
|
|
},
|
|
|
|
|
_ref
|
|
|
|
|
) => {
|
|
|
|
|
return (
|
|
|
|
|
<div>
|
|
|
|
|
{roles.length > 0 && (
|
|
|
|
|
<div className={menuSectionStyle}>
|
|
|
|
|
<div className={groupHeaderStyle}>{renderedName}</div>
|
|
|
|
|
<div className={optionBodyStyle}></div>
|
|
|
|
|
{showGroups && !!optionGroups?.length
|
2022-12-20 18:43:48 +08:00
|
|
|
? optionGroups.map((groupOption) => (
|
2022-12-20 18:05:37 +08:00
|
|
|
<RoleMenuGroupOption
|
2022-12-20 18:43:48 +08:00
|
|
|
data={groupOption}
|
|
|
|
|
key={groupOption.value}
|
|
|
|
|
isSelected={groupSelected(groupOption.value) || groupPartiallySelected(groupOption.value)}
|
|
|
|
|
partiallySelected={groupPartiallySelected(groupOption.value)}
|
|
|
|
|
disabled={groupOption.options?.every(isNotDelegatable)}
|
2022-12-20 18:05:37 +08:00
|
|
|
onChange={onChange}
|
|
|
|
|
onOpenSubMenu={onOpenSubMenuRMGS}
|
|
|
|
|
onCloseSubMenu={onCloseSubMenu}
|
|
|
|
|
root={subMenuNode}
|
2022-12-20 18:43:48 +08:00
|
|
|
isFocused={showSubMenu && openedMenuGroup === groupOption.value}
|
2022-12-20 18:05:37 +08:00
|
|
|
>
|
2022-12-20 18:43:48 +08:00
|
|
|
{showSubMenu && openedMenuGroup === groupOption.value && (
|
2022-12-20 18:05:37 +08:00
|
|
|
<RolePickerSubMenu
|
|
|
|
|
options={subMenuOptions}
|
|
|
|
|
selectedOptions={selectedOptions}
|
|
|
|
|
onSelect={onChangeSubMenu}
|
|
|
|
|
onClear={onClearSubMenu}
|
|
|
|
|
showOnLeft={showOnLeftSubMenu}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</RoleMenuGroupOption>
|
|
|
|
|
))
|
|
|
|
|
: roles.map((option) => (
|
|
|
|
|
<RoleMenuOption
|
|
|
|
|
data={option}
|
|
|
|
|
key={option.uid}
|
|
|
|
|
isSelected={!!(option.uid && !!selectedOptions.find((opt) => opt.uid === option.uid))}
|
|
|
|
|
disabled={isNotDelegatable(option)}
|
|
|
|
|
onChange={onChangeSubMenu}
|
|
|
|
|
hideDescription
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
RoleMenuGroupsSection.displayName = 'RoleMenuGroupsSection';
|