mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-06 00:07:44 +01:00
3acb3ad2c2
**Upgrade to React v18 for Unleash v6. Here's why I think it's a good time to do it:** - Command Bar project: We've begun work on the command bar project, and there's a fantastic library we want to use. However, it requires React v18 support. - Straightforward Upgrade: I took a look at the upgrade guide https://react.dev/blog/2022/03/08/react-18-upgrade-guide and it seems fairly straightforward. In fact, I was able to get React v18 running with minimal changes in just 10 minutes! - Dropping IE Support: React v18 no longer supports Internet Explorer (IE), which is no longer supported by Microsoft as of June 15, 2022. Upgrading to v18 in v6 would be a good way to align with this change. TS updates: * FC children has to be explicit: https://stackoverflow.com/questions/71788254/react-18-typescript-children-fc * forcing version 18 types in resolutions: https://sentry.io/answers/type-is-not-assignable-to-type-reactnode/ Test updates: * fixing SWR issue that we have always had but it manifests more in new React (https://github.com/vercel/swr/issues/2373) --------- Co-authored-by: kwasniew <kwasniewski.mateusz@gmail.com>
147 lines
3.8 KiB
TypeScript
147 lines
3.8 KiB
TypeScript
import { Button, type ButtonProps } from '@mui/material';
|
|
import Lock from '@mui/icons-material/Lock';
|
|
import React from 'react';
|
|
import {
|
|
TooltipResolver,
|
|
type ITooltipResolverProps,
|
|
} from 'component/common/TooltipResolver/TooltipResolver';
|
|
import { formatAccessText } from 'utils/formatAccessText';
|
|
import { useId } from 'hooks/useId';
|
|
import {
|
|
useHasRootAccess,
|
|
useHasProjectEnvironmentAccess,
|
|
} from 'hooks/useHasAccess';
|
|
|
|
export interface IPermissionButtonProps extends Omit<ButtonProps, 'title'> {
|
|
permission: string | string[];
|
|
onClick?: (e: any) => void;
|
|
disabled?: boolean;
|
|
projectId?: string;
|
|
environmentId?: string;
|
|
tooltipProps?: Omit<ITooltipResolverProps, 'children'>;
|
|
hideLockIcon?: boolean;
|
|
children?: React.ReactNode;
|
|
}
|
|
|
|
interface IPermissionBaseButtonProps extends IPermissionButtonProps {
|
|
access: boolean;
|
|
}
|
|
|
|
export interface IProjectPermissionButtonProps extends IPermissionButtonProps {
|
|
projectId: string;
|
|
environmentId: string;
|
|
}
|
|
|
|
const getEndIcon = (
|
|
access: boolean,
|
|
fallBackIcon?: React.ReactNode,
|
|
hideLockIcon?: boolean,
|
|
): React.ReactNode => {
|
|
if (!access && !hideLockIcon) {
|
|
return <Lock titleAccess='Locked' />;
|
|
}
|
|
|
|
if (fallBackIcon) {
|
|
return fallBackIcon;
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
const ProjectEnvironmentPermissionButton = React.forwardRef<
|
|
HTMLButtonElement,
|
|
IProjectPermissionButtonProps
|
|
>((props, ref) => {
|
|
const access = useHasProjectEnvironmentAccess(
|
|
props.permission,
|
|
props.projectId,
|
|
props.environmentId,
|
|
);
|
|
|
|
return <BasePermissionButton {...props} access={access} ref={ref} />;
|
|
});
|
|
|
|
const RootPermissionButton = React.forwardRef<
|
|
HTMLButtonElement,
|
|
IPermissionButtonProps
|
|
>((props, ref) => {
|
|
const access = useHasRootAccess(
|
|
props.permission,
|
|
props.projectId,
|
|
props.environmentId,
|
|
);
|
|
|
|
return <BasePermissionButton {...props} access={access} ref={ref} />;
|
|
});
|
|
|
|
const BasePermissionButton = React.forwardRef<
|
|
HTMLButtonElement,
|
|
IPermissionBaseButtonProps
|
|
>(
|
|
(
|
|
{
|
|
permission,
|
|
access,
|
|
variant = 'contained',
|
|
color = 'primary',
|
|
onClick,
|
|
children,
|
|
disabled,
|
|
projectId,
|
|
environmentId,
|
|
tooltipProps,
|
|
hideLockIcon,
|
|
...rest
|
|
},
|
|
ref,
|
|
) => {
|
|
const id = useId();
|
|
const endIcon = getEndIcon(access, rest.endIcon, hideLockIcon);
|
|
|
|
return (
|
|
<TooltipResolver
|
|
{...tooltipProps}
|
|
title={formatAccessText(access, tooltipProps?.title)}
|
|
arrow
|
|
>
|
|
<span id={id}>
|
|
<Button
|
|
ref={ref}
|
|
onClick={onClick}
|
|
disabled={disabled || !access}
|
|
aria-labelledby={id}
|
|
variant={variant}
|
|
color={color}
|
|
{...rest}
|
|
endIcon={endIcon}
|
|
>
|
|
{children}
|
|
</Button>
|
|
</span>
|
|
</TooltipResolver>
|
|
);
|
|
},
|
|
);
|
|
|
|
const PermissionButton = React.forwardRef<
|
|
HTMLButtonElement,
|
|
IPermissionButtonProps
|
|
>((props, ref) => {
|
|
if (
|
|
typeof props.projectId !== 'undefined' &&
|
|
typeof props.environmentId !== 'undefined'
|
|
) {
|
|
return (
|
|
<ProjectEnvironmentPermissionButton
|
|
{...props}
|
|
environmentId={props.environmentId}
|
|
projectId={props.projectId}
|
|
ref={ref}
|
|
/>
|
|
);
|
|
}
|
|
return <RootPermissionButton {...props} ref={ref} />;
|
|
});
|
|
|
|
export default PermissionButton;
|