From a9ac81a08946e0c5d3cd189862f9b56c7348016c Mon Sep 17 00:00:00 2001 From: Tymoteusz Czech <2625371+Tymek@users.noreply.github.com> Date: Mon, 11 Sep 2023 10:01:20 +0200 Subject: [PATCH] feat: useUiFlag shorthand hook (#4566) ## About the changes Instead of this: ```ts const { uiConfig } = useUiConfig(); const myFlag = Boolean(uiConfig?.flags?.myFlag) ``` we can have this: ```ts const myFlag = useUiFlag("myFlag") ``` With the same type safety, less verbose and more purposeful code. ### Important files - `frontend/src/hooks/useUiFlag.ts` ## Discussion points Can we in the future share flags between frontend and backend? Right now adding a new flag has to be done in 4 different places (backend flag keys list, backend flags defaults config, backend experimental server options, frontend type). Most ergonomic option is to pull config directly from Unleash. Issue, based on previous user feedback: https://github.com/Unleash/unleash/issues/4565 Internal feature request document: [docs.google.com/document/d/1Sx0q...](https://docs.google.com/document/d/1Sx0qKZXUVUCjuY5F4MOh1ieOM1A2_jE58zEA7jaM_1g/edit?usp=sharing) --- .../component/menu/Header/DrawerMenu/DrawerMenu.tsx | 3 --- frontend/src/component/menu/Header/Header.tsx | 1 - frontend/src/hooks/useUiFlag.ts | 9 +++++++++ frontend/src/interfaces/route.ts | 6 +++--- frontend/src/interfaces/uiConfig.ts | 13 ++++++++++--- 5 files changed, 22 insertions(+), 10 deletions(-) create mode 100644 frontend/src/hooks/useUiFlag.ts diff --git a/frontend/src/component/menu/Header/DrawerMenu/DrawerMenu.tsx b/frontend/src/component/menu/Header/DrawerMenu/DrawerMenu.tsx index 1d773ef187c0..61a3e4c6fffd 100644 --- a/frontend/src/component/menu/Header/DrawerMenu/DrawerMenu.tsx +++ b/frontend/src/component/menu/Header/DrawerMenu/DrawerMenu.tsx @@ -8,7 +8,6 @@ import { ReactComponent as UnleashLogo } from 'assets/img/logoDarkWithText.svg'; import { ReactComponent as UnleashLogoWhite } from 'assets/img/logoWithWhiteText.svg'; import NavigationLink from '../NavigationLink/NavigationLink'; import { basePath } from 'utils/formatPath'; -import { IFlags } from 'interfaces/uiConfig'; import { INavigationMenuItem } from 'interfaces/route'; import styles from './DrawerMenu.module.scss'; // FIXME: useStyle - theme import theme from 'themes/theme'; @@ -36,7 +35,6 @@ interface IDrawerMenuProps { href: string; title: string; }>; - flags?: IFlags; routes: { mainNavRoutes: INavigationMenuItem[]; mobileRoutes: INavigationMenuItem[]; @@ -46,7 +44,6 @@ interface IDrawerMenuProps { export const DrawerMenu: VFC = ({ links = [], - flags = {}, open = false, toggleDrawer, routes, diff --git a/frontend/src/component/menu/Header/Header.tsx b/frontend/src/component/menu/Header/Header.tsx index 8881262cea2f..8dc31766c5bf 100644 --- a/frontend/src/component/menu/Header/Header.tsx +++ b/frontend/src/component/menu/Header/Header.tsx @@ -147,7 +147,6 @@ const Header: VFC = () => { ['uiConfig']['flags']; + +export const useUiFlag = (flag: K) => { + const { uiConfig } = useUiConfig(); + + return uiConfig?.flags?.[flag] || false; +}; diff --git a/frontend/src/interfaces/route.ts b/frontend/src/interfaces/route.ts index 8755f8155336..06a38243bbaa 100644 --- a/frontend/src/interfaces/route.ts +++ b/frontend/src/interfaces/route.ts @@ -1,5 +1,5 @@ import { VoidFunctionComponent } from 'react'; -import { IFlags, IUiConfig } from 'interfaces/uiConfig'; +import { UiFlags, IUiConfig } from 'interfaces/uiConfig'; export interface IRoute { path: string; @@ -7,7 +7,7 @@ export interface IRoute { type: 'protected' | 'unprotected'; layout?: string; parent?: string; - flag?: keyof IFlags; + flag?: keyof UiFlags; configFlag?: keyof IUiConfig; hidden?: boolean; enterprise?: boolean; @@ -20,7 +20,7 @@ export interface INavigationMenuItem { path: string; title: string; menu: IRouteMenu; - flag?: keyof IFlags; + flag?: keyof UiFlags; configFlag?: keyof IUiConfig; group?: string; } diff --git a/frontend/src/interfaces/uiConfig.ts b/frontend/src/interfaces/uiConfig.ts index a6c48096efe4..be189c7201eb 100644 --- a/frontend/src/interfaces/uiConfig.ts +++ b/frontend/src/interfaces/uiConfig.ts @@ -4,7 +4,14 @@ import { Variant } from 'utils/variants'; export interface IUiConfig { authenticationType?: string; baseUriPath?: string; - flags: IFlags; + /** + * @deprecated `useUiFlags` can be used instead + * @example + * ```ts + * const yourFlag = useUiFlags("yourFlag") + * ``` + */ + flags: UiFlags; name: string; slogan: string; environment?: string; @@ -29,7 +36,7 @@ export interface IProclamationToast { link: string; } -export interface IFlags { +export type UiFlags = { P: boolean; RE: boolean; EEA?: boolean; @@ -59,7 +66,7 @@ export interface IFlags { featureNamingPattern?: boolean; doraMetrics?: boolean; [key: string]: boolean | Variant | undefined; -} +}; export interface IVersionInfo { instanceId: string;