2021-12-14 19:14:53 +00:00
|
|
|
import clsx from 'clsx';
|
2023-02-07 03:33:57 +00:00
|
|
|
import { Icon as ReactFeatherComponentType, Check } from 'lucide-react';
|
2021-12-14 19:14:53 +00:00
|
|
|
|
2022-11-13 08:10:18 +00:00
|
|
|
import { isLimitedToBE } from '@/react/portainer/feature-flags/feature-flags.service';
|
2022-06-23 06:32:18 +00:00
|
|
|
import { Icon } from '@/react/components/Icon';
|
2021-12-14 19:14:53 +00:00
|
|
|
|
2023-02-07 03:33:57 +00:00
|
|
|
import { BadgeIcon } from '@@/BadgeIcon';
|
2021-12-14 19:14:53 +00:00
|
|
|
|
2023-02-07 03:33:57 +00:00
|
|
|
import styles from './BoxSelectorItem.module.css';
|
|
|
|
import { BoxSelectorOption, Value } from './types';
|
2022-08-10 04:12:20 +00:00
|
|
|
import { LimitedToBeIndicator } from './LimitedToBeIndicator';
|
|
|
|
import { BoxOption } from './BoxOption';
|
2023-02-07 03:33:57 +00:00
|
|
|
import { LogoIcon } from './LogoIcon';
|
2021-12-14 19:14:53 +00:00
|
|
|
|
2023-02-07 03:33:57 +00:00
|
|
|
type Props<T extends Value> = {
|
2021-12-14 19:14:53 +00:00
|
|
|
option: BoxSelectorOption<T>;
|
2023-02-07 03:33:57 +00:00
|
|
|
radioName: string;
|
2021-12-14 19:14:53 +00:00
|
|
|
disabled?: boolean;
|
|
|
|
tooltip?: string;
|
2023-02-07 03:33:57 +00:00
|
|
|
onSelect(value: T, limitedToBE: boolean): void;
|
|
|
|
isSelected(value: T): boolean;
|
|
|
|
type?: 'radio' | 'checkbox';
|
|
|
|
slim?: boolean;
|
|
|
|
checkIcon?: ReactFeatherComponentType;
|
|
|
|
};
|
2021-12-14 19:14:53 +00:00
|
|
|
|
2023-02-07 03:33:57 +00:00
|
|
|
export function BoxSelectorItem<T extends Value>({
|
2021-12-14 19:14:53 +00:00
|
|
|
radioName,
|
|
|
|
option,
|
2023-02-07 03:33:57 +00:00
|
|
|
onSelect = () => {},
|
2021-12-14 19:14:53 +00:00
|
|
|
disabled,
|
|
|
|
tooltip,
|
2023-02-07 03:33:57 +00:00
|
|
|
type = 'radio',
|
|
|
|
isSelected,
|
|
|
|
slim = false,
|
|
|
|
checkIcon = Check,
|
2021-12-14 19:14:53 +00:00
|
|
|
}: Props<T>) {
|
|
|
|
const limitedToBE = isLimitedToBE(option.feature);
|
|
|
|
|
2022-08-10 04:12:20 +00:00
|
|
|
const beIndicatorTooltipId = `box-selector-item-${radioName}-${option.id}-limited`;
|
2021-12-14 19:14:53 +00:00
|
|
|
return (
|
2022-08-10 04:12:20 +00:00
|
|
|
<BoxOption
|
2023-02-07 03:33:57 +00:00
|
|
|
className={clsx(styles.boxSelectorItem, {
|
|
|
|
[styles.business]: limitedToBE,
|
|
|
|
[styles.limited]: limitedToBE,
|
2021-12-14 19:14:53 +00:00
|
|
|
})}
|
2022-08-10 04:12:20 +00:00
|
|
|
radioName={radioName}
|
|
|
|
option={option}
|
2023-02-07 03:33:57 +00:00
|
|
|
isSelected={isSelected}
|
|
|
|
disabled={isDisabled()}
|
|
|
|
onSelect={(value) => onSelect(value, limitedToBE)}
|
2022-08-10 04:12:20 +00:00
|
|
|
tooltip={tooltip}
|
2023-02-07 03:33:57 +00:00
|
|
|
type={type}
|
|
|
|
checkIcon={checkIcon}
|
2021-12-14 19:14:53 +00:00
|
|
|
>
|
2022-08-10 04:12:20 +00:00
|
|
|
<>
|
|
|
|
{limitedToBE && (
|
2022-09-02 00:42:48 +00:00
|
|
|
<LimitedToBeIndicator
|
|
|
|
tooltipId={beIndicatorTooltipId}
|
|
|
|
featureId={option.feature}
|
|
|
|
/>
|
2022-08-10 04:12:20 +00:00
|
|
|
)}
|
2023-02-07 03:33:57 +00:00
|
|
|
<div
|
|
|
|
className={clsx('flex gap-2', {
|
|
|
|
'opacity-30': limitedToBE,
|
2023-02-12 21:04:24 +00:00
|
|
|
'h-full flex-col justify-between': !slim,
|
|
|
|
'slim items-center': slim,
|
2023-02-07 03:33:57 +00:00
|
|
|
})}
|
|
|
|
>
|
|
|
|
<div
|
|
|
|
className={clsx(styles.imageContainer, 'flex items-center', {
|
|
|
|
'flex-1': !slim,
|
|
|
|
})}
|
|
|
|
>
|
|
|
|
{renderIcon()}
|
|
|
|
</div>
|
|
|
|
<div>
|
|
|
|
<div className={styles.header}>{option.label}</div>
|
|
|
|
<p>{option.description}</p>
|
2022-08-10 04:12:20 +00:00
|
|
|
</div>
|
2021-12-14 19:14:53 +00:00
|
|
|
</div>
|
2022-08-10 04:12:20 +00:00
|
|
|
</>
|
|
|
|
</BoxOption>
|
2021-12-14 19:14:53 +00:00
|
|
|
);
|
2023-02-07 03:33:57 +00:00
|
|
|
|
|
|
|
function isDisabled() {
|
|
|
|
return disabled || (limitedToBE && option.disabledWhenLimited);
|
|
|
|
}
|
|
|
|
|
|
|
|
function renderIcon() {
|
|
|
|
if (!option.icon) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (option.iconType === 'badge') {
|
|
|
|
return <BadgeIcon icon={option.icon} />;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (option.iconType === 'logo') {
|
|
|
|
return <LogoIcon icon={option.icon} />;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Icon
|
|
|
|
icon={option.icon}
|
|
|
|
className={clsx(styles.icon, '!flex items-center')}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
2021-12-14 19:14:53 +00:00
|
|
|
}
|