mirror of
https://github.com/portainer/portainer.git
synced 2025-07-23 15:29:42 +02:00
refactor(ui/box-selector): replace all selectors [EE-3856] (#7902)
This commit is contained in:
parent
c9253319d9
commit
2dddc1c6b9
80 changed files with 1267 additions and 1011 deletions
|
@ -1,46 +1,57 @@
|
|||
import clsx from 'clsx';
|
||||
import { Icon as ReactFeatherComponentType, Check } from 'lucide-react';
|
||||
|
||||
import { isLimitedToBE } from '@/react/portainer/feature-flags/feature-flags.service';
|
||||
import { Icon } from '@/react/components/Icon';
|
||||
|
||||
import './BoxSelectorItem.css';
|
||||
import { BadgeIcon } from '@@/BadgeIcon';
|
||||
|
||||
import { BoxSelectorOption } from './types';
|
||||
import styles from './BoxSelectorItem.module.css';
|
||||
import { BoxSelectorOption, Value } from './types';
|
||||
import { LimitedToBeIndicator } from './LimitedToBeIndicator';
|
||||
import { BoxOption } from './BoxOption';
|
||||
import { LogoIcon } from './LogoIcon';
|
||||
|
||||
interface Props<T extends number | string> {
|
||||
radioName: string;
|
||||
type Props<T extends Value> = {
|
||||
option: BoxSelectorOption<T>;
|
||||
onChange(value: T, limitedToBE: boolean): void;
|
||||
selectedValue: T;
|
||||
radioName: string;
|
||||
disabled?: boolean;
|
||||
tooltip?: string;
|
||||
}
|
||||
onSelect(value: T, limitedToBE: boolean): void;
|
||||
isSelected(value: T): boolean;
|
||||
type?: 'radio' | 'checkbox';
|
||||
slim?: boolean;
|
||||
checkIcon?: ReactFeatherComponentType;
|
||||
};
|
||||
|
||||
export function BoxSelectorItem<T extends number | string>({
|
||||
export function BoxSelectorItem<T extends Value>({
|
||||
radioName,
|
||||
option,
|
||||
onChange,
|
||||
selectedValue,
|
||||
onSelect = () => {},
|
||||
disabled,
|
||||
tooltip,
|
||||
type = 'radio',
|
||||
isSelected,
|
||||
slim = false,
|
||||
checkIcon = Check,
|
||||
}: Props<T>) {
|
||||
const limitedToBE = isLimitedToBE(option.feature);
|
||||
|
||||
const beIndicatorTooltipId = `box-selector-item-${radioName}-${option.id}-limited`;
|
||||
return (
|
||||
<BoxOption
|
||||
className={clsx({
|
||||
business: limitedToBE,
|
||||
limited: limitedToBE,
|
||||
className={clsx(styles.boxSelectorItem, {
|
||||
[styles.business]: limitedToBE,
|
||||
[styles.limited]: limitedToBE,
|
||||
})}
|
||||
radioName={radioName}
|
||||
option={option}
|
||||
selectedValue={selectedValue}
|
||||
disabled={disabled}
|
||||
onChange={(value) => onChange(value, limitedToBE)}
|
||||
isSelected={isSelected}
|
||||
disabled={isDisabled()}
|
||||
onSelect={(value) => onSelect(value, limitedToBE)}
|
||||
tooltip={tooltip}
|
||||
type={type}
|
||||
checkIcon={checkIcon}
|
||||
>
|
||||
<>
|
||||
{limitedToBE && (
|
||||
|
@ -49,19 +60,51 @@ export function BoxSelectorItem<T extends number | string>({
|
|||
featureId={option.feature}
|
||||
/>
|
||||
)}
|
||||
<div className={clsx({ 'opacity-30': limitedToBE })}>
|
||||
<div className="boxselector_img_container">
|
||||
{!!option.icon && (
|
||||
<Icon
|
||||
icon={option.icon}
|
||||
className="boxselector_icon !flex items-center"
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
className={clsx('flex gap-2', {
|
||||
'opacity-30': limitedToBE,
|
||||
'flex-col justify-between h-full': !slim,
|
||||
'items-center slim': slim,
|
||||
})}
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
<div className="boxselector_header">{option.label}</div>
|
||||
<p className="box-selector-item-description">{option.description}</p>
|
||||
</div>
|
||||
</>
|
||||
</BoxOption>
|
||||
);
|
||||
|
||||
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')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue