mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	**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;
 |