From a566cba67171d37ffa6a626616c94692d9bc132b Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Thu, 10 Sep 2020 16:18:24 +0200 Subject: [PATCH 01/11] wip: big commit to add sidebar settings dialog --- .../core/src/layout/Sidebar/PinButton.tsx | 75 ---------------- .../src/layout/Sidebar/Settings/PinButton.tsx | 64 ++++++++++++++ .../Sidebar/Settings/ProviderSettingsItem.tsx | 52 +++++++---- .../Sidebar/Settings/SettingsDialog.tsx | 70 +++++++++++++++ .../layout/Sidebar/Settings/SignInAvatar.tsx | 63 ++++++++++++++ .../layout/Sidebar/Settings/ThemeToggle.tsx | 87 +++++++++++++++++++ .../layout/Sidebar/Settings/UserProfile.tsx | 61 ------------- .../layout/Sidebar/Settings/UserSettings.tsx | 78 +++++++++++++++++ .../Sidebar/Settings/UserSettingsMenu.tsx | 55 ++++++++++++ .../core/src/layout/Sidebar/Settings/index.ts | 3 +- .../Sidebar/Settings/useUserProfileInfo.ts | 26 ++++++ .../src/layout/Sidebar/SidebarThemeToggle.tsx | 58 ------------- .../core/src/layout/Sidebar/UserSettings.tsx | 53 ----------- packages/core/src/layout/Sidebar/index.ts | 7 +- 14 files changed, 486 insertions(+), 266 deletions(-) delete mode 100644 packages/core/src/layout/Sidebar/PinButton.tsx create mode 100644 packages/core/src/layout/Sidebar/Settings/PinButton.tsx create mode 100644 packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx create mode 100644 packages/core/src/layout/Sidebar/Settings/SignInAvatar.tsx create mode 100644 packages/core/src/layout/Sidebar/Settings/ThemeToggle.tsx delete mode 100644 packages/core/src/layout/Sidebar/Settings/UserProfile.tsx create mode 100644 packages/core/src/layout/Sidebar/Settings/UserSettings.tsx create mode 100644 packages/core/src/layout/Sidebar/Settings/UserSettingsMenu.tsx create mode 100644 packages/core/src/layout/Sidebar/Settings/useUserProfileInfo.ts delete mode 100644 packages/core/src/layout/Sidebar/SidebarThemeToggle.tsx delete mode 100644 packages/core/src/layout/Sidebar/UserSettings.tsx diff --git a/packages/core/src/layout/Sidebar/PinButton.tsx b/packages/core/src/layout/Sidebar/PinButton.tsx deleted file mode 100644 index 8c52eeb24d..0000000000 --- a/packages/core/src/layout/Sidebar/PinButton.tsx +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { FC, useContext } from 'react'; -import { makeStyles } from '@material-ui/core'; -import DoubleArrowIcon from '@material-ui/icons/DoubleArrow'; -import { SidebarContext } from './config'; -import { BackstageTheme } from '@backstage/theme'; -import { SidebarPinStateContext } from './Page'; - -const ARROW_BUTTON_SIZE = 20; -const useStyles = makeStyles(theme => { - return { - root: { - position: 'relative', - alignSelf: 'stretch', - }, - arrowButtonWrapper: { - position: 'absolute', - right: 0, - width: ARROW_BUTTON_SIZE, - height: ARROW_BUTTON_SIZE, - top: -(theme.spacing(6) + ARROW_BUTTON_SIZE) / 2, - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - borderRadius: '2px 0px 0px 2px', - background: theme.palette.pinSidebarButton.background, - color: theme.palette.pinSidebarButton.icon, - border: 'none', - outline: 'none', - cursor: 'pointer', - }, - arrowButtonIcon: { - transform: ({ isPinned }) => (isPinned ? 'rotate(180deg)' : 'none'), - }, - }; -}); - -export const SidebarPinButton: FC<{}> = () => { - const { isOpen } = useContext(SidebarContext); - const { isPinned, toggleSidebarPinState } = useContext( - SidebarPinStateContext, - ); - const classes = useStyles({ isPinned }); - - return ( -
- {isOpen && ( - - )} -
- ); -}; diff --git a/packages/core/src/layout/Sidebar/Settings/PinButton.tsx b/packages/core/src/layout/Sidebar/Settings/PinButton.tsx new file mode 100644 index 0000000000..dcd0818ad6 --- /dev/null +++ b/packages/core/src/layout/Sidebar/Settings/PinButton.tsx @@ -0,0 +1,64 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { useContext } from 'react'; +import { + ListItem, + ListItemSecondaryAction, + ListItemText, + Tooltip, +} from '@material-ui/core'; +import LockIcon from '@material-ui/icons/Lock'; +import LockOpenIcon from '@material-ui/icons/LockOpen'; +import { ToggleButton } from '@material-ui/lab'; +import { SidebarPinStateContext } from '../Page'; + +export const SidebarPinButton = () => { + const { isPinned, toggleSidebarPinState } = useContext( + SidebarPinStateContext, + ); + + const PinIcon = () => ( + + {isPinned ? : } + + ); + + return ( + + + + { + toggleSidebarPinState(); + }} + > + + + + + ); +}; diff --git a/packages/core/src/layout/Sidebar/Settings/ProviderSettingsItem.tsx b/packages/core/src/layout/Sidebar/Settings/ProviderSettingsItem.tsx index 3d3d7439e1..653c64575b 100644 --- a/packages/core/src/layout/Sidebar/Settings/ProviderSettingsItem.tsx +++ b/packages/core/src/layout/Sidebar/Settings/ProviderSettingsItem.tsx @@ -14,31 +14,53 @@ * limitations under the License. */ -import React, { FC } from 'react'; -import { OAuthApi, OpenIdConnectApi, IconComponent } from '@backstage/core-api'; -import { SidebarItem } from '../Items'; -import { IconButton, Tooltip } from '@material-ui/core'; -import StarBorder from '@material-ui/icons/StarBorder'; +import React from 'react'; +import { IconComponent, OAuthApi, OpenIdConnectApi } from '@backstage/core-api'; +import { + ListItem, + ListItemIcon, + ListItemSecondaryAction, + ListItemText, + Tooltip, +} from '@material-ui/core'; import PowerButton from '@material-ui/icons/PowerSettingsNew'; +import { ToggleButton } from '@material-ui/lab'; -export const ProviderSettingsItem: FC<{ +type Props = { title: string; icon: IconComponent; signedIn: boolean; api: OAuthApi | OpenIdConnectApi; signInHandler: Function; -}> = ({ title, icon, signedIn, api, signInHandler }) => { - return ( - - (signedIn ? api.logout() : signInHandler())}> +}; + +export const ProviderSettingsItem = ({ + title, + icon: Icon, + signedIn, + api, + signInHandler, +}: Props) => ( + + + + + + + (signedIn ? api.logout() : signInHandler())} + > - + - - - ); -}; + + + +); diff --git a/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx b/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx new file mode 100644 index 0000000000..b37053763b --- /dev/null +++ b/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx @@ -0,0 +1,70 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { + Card, + CardContent, + CardHeader, + Divider, + makeStyles, +} from '@material-ui/core'; +import List from '@material-ui/core/List'; +import ListSubheader from '@material-ui/core/ListSubheader'; +import { SidebarPinButton } from './PinButton'; +import { SignInAvatar } from './SignInAvatar'; +import { SidebarThemeToggle } from './ThemeToggle'; +import { UserSettingsMenu } from './UserSettingsMenu'; +import { useUserProfile } from './useUserProfileInfo'; + +const useStyles = makeStyles({ + root: { + minWidth: 400, + }, +}); + +export const SettingsDialog = ({ + providerSettings, +}: { + providerSettings?: React.ReactNode; +}) => { + const classes = useStyles(); + const { profile, displayName } = useUserProfile(); + + return ( + + } + action={} + title={displayName} + subheader={profile.email} + /> + + + App Settings}> + + + + + Available Auth Providers} + > + {providerSettings} + + + + ); +}; diff --git a/packages/core/src/layout/Sidebar/Settings/SignInAvatar.tsx b/packages/core/src/layout/Sidebar/Settings/SignInAvatar.tsx new file mode 100644 index 0000000000..c6eed74a18 --- /dev/null +++ b/packages/core/src/layout/Sidebar/Settings/SignInAvatar.tsx @@ -0,0 +1,63 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { BackstageTheme } from '@backstage/theme'; +import { makeStyles, Avatar } from '@material-ui/core'; +import { useUserProfile } from './useUserProfileInfo'; + +// const useStyles = makeStyles({ +// avatar: { +// width: ({ size }) => size, +// height: ({ size }) => size, +// }, +// }); + +// export const SignInAvatar = ({ size = 24 }: { size?: number }) => { +// const classes = useStyles({ size }); +// const { profile, displayName } = useUserProfile(); + +// return ( +// +// {displayName[0]} +// +// ); +// }; + +// const useStyles = makeStyles({ +// avatar: { +// width: 24, +// height: 24, +// }, +// }); + +const useStyles = makeStyles({ + avatar: { + width: 24, + height: 24, + }, +}); + +export const SignInAvatar = () => { + const classes = useStyles(); + const { profile, displayName } = useUserProfile(); + + return ( + + {displayName[0]} + + ); +}; diff --git a/packages/core/src/layout/Sidebar/Settings/ThemeToggle.tsx b/packages/core/src/layout/Sidebar/Settings/ThemeToggle.tsx new file mode 100644 index 0000000000..29cfb24885 --- /dev/null +++ b/packages/core/src/layout/Sidebar/Settings/ThemeToggle.tsx @@ -0,0 +1,87 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { useObservable } from 'react-use'; +import LightIcon from '@material-ui/icons/WbSunny'; +import DarkIcon from '@material-ui/icons/Brightness2'; +import AutoIcon from '@material-ui/icons/BrightnessAuto'; +import { appThemeApiRef, useApi } from '@backstage/core-api'; +import ToggleButton from '@material-ui/lab/ToggleButton'; +import ToggleButtonGroup from '@material-ui/lab/ToggleButtonGroup'; +import { + ListItem, + ListItemText, + ListItemSecondaryAction, + Tooltip, +} from '@material-ui/core'; + +export const SidebarThemeToggle = () => { + const appThemeApi = useApi(appThemeApiRef); + const themeId = useObservable( + appThemeApi.activeThemeId$(), + appThemeApi.getActiveThemeId(), + ); + + const themeIds = appThemeApi.getInstalledThemes(); + // TODO: can these be put on the theme itself? + const themeIcons = { + dark: , + light: , + }; + + const handleSetTheme = ( + _event: React.MouseEvent, + newThemeId: string | undefined, + ) => { + if (themeIds.some(t => t.id === newThemeId)) { + appThemeApi.setActiveThemeId(newThemeId); + } else { + appThemeApi.setActiveThemeId(undefined); + } + }; + + return ( + + + + + {themeIds.map(theme => ( + + + {themeIcons[theme.variant]} + + + ))} + + + + + + + + + ); +}; diff --git a/packages/core/src/layout/Sidebar/Settings/UserProfile.tsx b/packages/core/src/layout/Sidebar/Settings/UserProfile.tsx deleted file mode 100644 index 3b854801c9..0000000000 --- a/packages/core/src/layout/Sidebar/Settings/UserProfile.tsx +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { FC, useRef } from 'react'; -import { makeStyles, Avatar, Divider } from '@material-ui/core'; -import { useApi, identityApiRef } from '@backstage/core-api'; -import { SidebarItem } from '../Items'; -import ExpandLess from '@material-ui/icons/ExpandLess'; -import ExpandMore from '@material-ui/icons/ExpandMore'; - -const useStyles = makeStyles({ - avatar: { - width: 24, - height: 24, - }, -}); - -export const UserProfile: FC<{ open: boolean; setOpen: Function }> = ({ - open, - setOpen, -}) => { - const ref = useRef(); // for scrolling down when collapse item opens - const classes = useStyles(); - const identityApi = useApi(identityApiRef); - - const handleClick = () => { - setOpen(!open); - setTimeout(() => ref.current?.scrollIntoView({ behavior: 'smooth' }), 300); - }; - - const userId = identityApi.getUserId(); - const profile = identityApi.getProfile(); - const displayName = profile.displayName ?? userId; - const SignInAvatar = () => ( - - {displayName[0]} - - ); - - return ( - <> - - - {open ? : } - - - ); -}; diff --git a/packages/core/src/layout/Sidebar/Settings/UserSettings.tsx b/packages/core/src/layout/Sidebar/Settings/UserSettings.tsx new file mode 100644 index 0000000000..8f541364ff --- /dev/null +++ b/packages/core/src/layout/Sidebar/Settings/UserSettings.tsx @@ -0,0 +1,78 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React, { useEffect, useContext } from 'react'; +import { Popover } from '@material-ui/core'; +import { SignInAvatar } from './SignInAvatar'; +import { SettingsDialog } from './SettingsDialog'; +import { SidebarItem } from '../Items'; +import { useUserProfile } from './useUserProfileInfo'; +import { SidebarContext } from '../config'; + +export const SidebarUserSettings = ({ + providerSettings, +}: { + providerSettings?: React.ReactNode; +}) => { + const { isOpen: sidebarOpen } = useContext(SidebarContext); + const { displayName } = useUserProfile(); + const [open, setOpen] = React.useState(false); + const [anchorEl, setAnchorEl] = React.useState( + undefined, + ); + + const handleOpen = (event?: React.MouseEvent) => { + setAnchorEl(event?.currentTarget ?? undefined); + setOpen(true); + }; + + const handleClose = () => { + setAnchorEl(undefined); + setOpen(false); + }; + + // Close the provider list when sidebar collapse + useEffect(() => { + if (!sidebarOpen && open) setOpen(false); + }, [open, sidebarOpen]); + + const SidebarAvatar = () => ; + + return ( + <> + + + + + + ); +}; diff --git a/packages/core/src/layout/Sidebar/Settings/UserSettingsMenu.tsx b/packages/core/src/layout/Sidebar/Settings/UserSettingsMenu.tsx new file mode 100644 index 0000000000..9ac287c57e --- /dev/null +++ b/packages/core/src/layout/Sidebar/Settings/UserSettingsMenu.tsx @@ -0,0 +1,55 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { identityApiRef, useApi } from '@backstage/core-api'; +import { IconButton, ListItemIcon, Menu, MenuItem } from '@material-ui/core'; +import SignOutIcon from '@material-ui/icons/MeetingRoom'; +import MoreVertIcon from '@material-ui/icons/MoreVert'; + +export const UserSettingsMenu = () => { + const identityApi = useApi(identityApiRef); + const [open, setOpen] = React.useState(false); + const [anchorEl, setAnchorEl] = React.useState( + undefined, + ); + + const handleOpen = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + setOpen(true); + }; + + const handleClose = () => { + setAnchorEl(undefined); + setOpen(false); + }; + + return ( + <> + + + + + identityApi.logout()}> + + + + Sign Out + + + + ); +}; diff --git a/packages/core/src/layout/Sidebar/Settings/index.ts b/packages/core/src/layout/Sidebar/Settings/index.ts index 6557ace53a..5479236a3b 100644 --- a/packages/core/src/layout/Sidebar/Settings/index.ts +++ b/packages/core/src/layout/Sidebar/Settings/index.ts @@ -17,4 +17,5 @@ export { ProviderSettingsItem } from './ProviderSettingsItem'; export { OAuthProviderSettings } from './OAuthProviderSettings'; export { OIDCProviderSettings } from './OIDCProviderSettings'; -export { UserProfile } from './UserProfile'; +// export { UserProfile } from './UserProfile'; +export { SidebarUserSettings } from './UserSettings'; diff --git a/packages/core/src/layout/Sidebar/Settings/useUserProfileInfo.ts b/packages/core/src/layout/Sidebar/Settings/useUserProfileInfo.ts new file mode 100644 index 0000000000..60dae294a5 --- /dev/null +++ b/packages/core/src/layout/Sidebar/Settings/useUserProfileInfo.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { useApi, identityApiRef } from '@backstage/core-api'; + +export const useUserProfile = () => { + const identityApi = useApi(identityApiRef); + const userId = identityApi.getUserId(); + const profile = identityApi.getProfile(); + const displayName = profile.displayName ?? userId; + + return { profile, displayName }; +}; diff --git a/packages/core/src/layout/Sidebar/SidebarThemeToggle.tsx b/packages/core/src/layout/Sidebar/SidebarThemeToggle.tsx deleted file mode 100644 index 32bc9d9632..0000000000 --- a/packages/core/src/layout/Sidebar/SidebarThemeToggle.tsx +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { FC } from 'react'; -import { useObservable } from 'react-use'; -import LightIcon from '@material-ui/icons/WbSunny'; -import DarkIcon from '@material-ui/icons/Brightness2'; -import AutoIcon from '@material-ui/icons/BrightnessAuto'; -import { appThemeApiRef, useApi } from '@backstage/core-api'; -import { SidebarItem } from './Items'; - -export const SidebarThemeToggle: FC<{}> = () => { - const appThemeApi = useApi(appThemeApiRef); - const themeId = useObservable( - appThemeApi.activeThemeId$(), - appThemeApi.getActiveThemeId(), - ); - - let text = 'Auto'; - let icon = AutoIcon; - switch (themeId) { - case 'dark': - text = 'Dark mode'; - icon = DarkIcon; - break; - case 'light': - text = 'Light mode'; - icon = LightIcon; - break; - default: - break; - } - - const handleToggle = () => { - if (!themeId) { - appThemeApi.setActiveThemeId('light'); - } else if (themeId === 'light') { - appThemeApi.setActiveThemeId('dark'); - } else { - appThemeApi.setActiveThemeId(undefined); - } - }; - - return ; -}; diff --git a/packages/core/src/layout/Sidebar/UserSettings.tsx b/packages/core/src/layout/Sidebar/UserSettings.tsx deleted file mode 100644 index f586f6d077..0000000000 --- a/packages/core/src/layout/Sidebar/UserSettings.tsx +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { identityApiRef, useApi } from '@backstage/core-api'; -import Collapse from '@material-ui/core/Collapse'; -import SignOutIcon from '@material-ui/icons/MeetingRoom'; -import React, { useContext, useEffect } from 'react'; -import { SidebarContext } from './config'; -import { SidebarItem } from './Items'; -import { UserProfile as SidebarUserProfile } from './Settings'; - -type SidebarUserSettingsProps = { providerSettings?: React.ReactNode }; - -export function SidebarUserSettings({ - providerSettings, -}: SidebarUserSettingsProps) { - const { isOpen: sidebarOpen } = useContext(SidebarContext); - const [open, setOpen] = React.useState(false); - const identityApi = useApi(identityApiRef); - - // Close the provider list when sidebar collapse - useEffect(() => { - if (!sidebarOpen && open) setOpen(false); - }, [open, sidebarOpen]); - - return ( - <> - - - {providerSettings} - - identityApi.logout()} - /> - - - ); -} diff --git a/packages/core/src/layout/Sidebar/index.ts b/packages/core/src/layout/Sidebar/index.ts index fdca7e4eea..fb9a457dea 100644 --- a/packages/core/src/layout/Sidebar/index.ts +++ b/packages/core/src/layout/Sidebar/index.ts @@ -25,14 +25,15 @@ export { SidebarSpacer, } from './Items'; export { IntroCard, SidebarIntro } from './Intro'; -export { SidebarPinButton } from './PinButton'; +// export { SidebarPinButton } from './PinButton'; export { SIDEBAR_INTRO_LOCAL_STORAGE, SidebarContext, sidebarConfig, } from './config'; export type { SidebarContextType } from './config'; -export { SidebarThemeToggle } from './SidebarThemeToggle'; -export { SidebarUserSettings } from './UserSettings'; +// export { SidebarThemeToggle } from './SidebarThemeToggle'; +// export { SidebarUserSettings } from './UserSettings'; export { DefaultProviderSettings } from './DefaultProviderSettings'; export * from './Settings'; +// export { SidebarUserSettings } from './UserSettings'; From 5e9acd5947b02bde74ebc77a787051db0812454a Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Thu, 10 Sep 2020 17:59:40 +0200 Subject: [PATCH 02/11] Option to change size of SignInAvatar --- .../Sidebar/Settings/SettingsDialog.tsx | 2 +- .../layout/Sidebar/Settings/SignInAvatar.tsx | 37 ++++--------------- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx b/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx index b37053763b..9077654b5c 100644 --- a/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx +++ b/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx @@ -47,7 +47,7 @@ export const SettingsDialog = ({ return ( } + avatar={} action={} title={displayName} subheader={profile.email} diff --git a/packages/core/src/layout/Sidebar/Settings/SignInAvatar.tsx b/packages/core/src/layout/Sidebar/Settings/SignInAvatar.tsx index c6eed74a18..519d467436 100644 --- a/packages/core/src/layout/Sidebar/Settings/SignInAvatar.tsx +++ b/packages/core/src/layout/Sidebar/Settings/SignInAvatar.tsx @@ -18,41 +18,18 @@ import React from 'react'; import { BackstageTheme } from '@backstage/theme'; import { makeStyles, Avatar } from '@material-ui/core'; import { useUserProfile } from './useUserProfileInfo'; +import { sidebarConfig } from '../config'; -// const useStyles = makeStyles({ -// avatar: { -// width: ({ size }) => size, -// height: ({ size }) => size, -// }, -// }); - -// export const SignInAvatar = ({ size = 24 }: { size?: number }) => { -// const classes = useStyles({ size }); -// const { profile, displayName } = useUserProfile(); - -// return ( -// -// {displayName[0]} -// -// ); -// }; - -// const useStyles = makeStyles({ -// avatar: { -// width: 24, -// height: 24, -// }, -// }); - -const useStyles = makeStyles({ +const useStyles = makeStyles({ avatar: { - width: 24, - height: 24, + width: ({ size }) => size, + height: ({ size }) => size, }, }); -export const SignInAvatar = () => { - const classes = useStyles(); +export const SignInAvatar = ({ size }: { size?: number }) => { + const { iconSize } = sidebarConfig; + const classes = useStyles(size ? { size } : { size: iconSize }); const { profile, displayName } = useUserProfile(); return ( From cd66f03f9d2ec31bc543bb1374ae754e6c6d9c74 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Fri, 11 Sep 2020 09:58:45 +0200 Subject: [PATCH 03/11] Cleanup and breaking out into more components --- .../Sidebar/Settings/AppSettingsList.tsx | 26 +++++++++++++++++ .../Sidebar/Settings/AuthProviderList.tsx | 29 +++++++++++++++++++ .../src/layout/Sidebar/Settings/PinButton.tsx | 2 +- .../Sidebar/Settings/SettingsDialog.tsx | 28 +++++++----------- .../layout/Sidebar/Settings/SignInAvatar.tsx | 4 ++- .../layout/Sidebar/Settings/ThemeToggle.tsx | 2 +- .../layout/Sidebar/Settings/UserSettings.tsx | 9 +++--- 7 files changed, 75 insertions(+), 25 deletions(-) create mode 100644 packages/core/src/layout/Sidebar/Settings/AppSettingsList.tsx create mode 100644 packages/core/src/layout/Sidebar/Settings/AuthProviderList.tsx diff --git a/packages/core/src/layout/Sidebar/Settings/AppSettingsList.tsx b/packages/core/src/layout/Sidebar/Settings/AppSettingsList.tsx new file mode 100644 index 0000000000..5dad178ccd --- /dev/null +++ b/packages/core/src/layout/Sidebar/Settings/AppSettingsList.tsx @@ -0,0 +1,26 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { List, ListSubheader } from '@material-ui/core'; +import { SidebarThemeToggle } from './ThemeToggle'; +import { SidebarPinButton } from './PinButton'; + +export const AppSettingsList = () => ( + App Settings}> + + + +); diff --git a/packages/core/src/layout/Sidebar/Settings/AuthProviderList.tsx b/packages/core/src/layout/Sidebar/Settings/AuthProviderList.tsx new file mode 100644 index 0000000000..5d13d61148 --- /dev/null +++ b/packages/core/src/layout/Sidebar/Settings/AuthProviderList.tsx @@ -0,0 +1,29 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import List from '@material-ui/core/List'; +import ListSubheader from '@material-ui/core/ListSubheader'; + +type Props = { + providerSettings?: React.ReactNode; +}; + +export const AuthProvidersList = ({ providerSettings }: Props) => ( + Available Auth Providers}> + {providerSettings} + +); diff --git a/packages/core/src/layout/Sidebar/Settings/PinButton.tsx b/packages/core/src/layout/Sidebar/Settings/PinButton.tsx index dcd0818ad6..2727313ede 100644 --- a/packages/core/src/layout/Sidebar/Settings/PinButton.tsx +++ b/packages/core/src/layout/Sidebar/Settings/PinButton.tsx @@ -50,7 +50,7 @@ export const SidebarPinButton = () => { { toggleSidebarPinState(); diff --git a/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx b/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx index 9077654b5c..ee2f0bdfb4 100644 --- a/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx +++ b/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx @@ -22,11 +22,10 @@ import { Divider, makeStyles, } from '@material-ui/core'; -import List from '@material-ui/core/List'; -import ListSubheader from '@material-ui/core/ListSubheader'; -import { SidebarPinButton } from './PinButton'; +import { AppSettingsList } from './AppSettingsList'; +import { AuthProvidersList } from './AuthProviderList'; +import { FeatureFlagsList } from './FeatureFlagsList'; import { SignInAvatar } from './SignInAvatar'; -import { SidebarThemeToggle } from './ThemeToggle'; import { UserSettingsMenu } from './UserSettingsMenu'; import { useUserProfile } from './useUserProfileInfo'; @@ -36,11 +35,11 @@ const useStyles = makeStyles({ }, }); -export const SettingsDialog = ({ - providerSettings, -}: { +type Props = { providerSettings?: React.ReactNode; -}) => { +}; + +export const SettingsDialog = ({ providerSettings }: Props) => { const classes = useStyles(); const { profile, displayName } = useUserProfile(); @@ -54,16 +53,11 @@ export const SettingsDialog = ({ /> - App Settings}> - - - + - Available Auth Providers} - > - {providerSettings} - + + + ); diff --git a/packages/core/src/layout/Sidebar/Settings/SignInAvatar.tsx b/packages/core/src/layout/Sidebar/Settings/SignInAvatar.tsx index 519d467436..f0430edfcf 100644 --- a/packages/core/src/layout/Sidebar/Settings/SignInAvatar.tsx +++ b/packages/core/src/layout/Sidebar/Settings/SignInAvatar.tsx @@ -27,7 +27,9 @@ const useStyles = makeStyles({ }, }); -export const SignInAvatar = ({ size }: { size?: number }) => { +type Props = { size?: number }; + +export const SignInAvatar = ({ size }: Props) => { const { iconSize } = sidebarConfig; const classes = useStyles(size ? { size } : { size: iconSize }); const { profile, displayName } = useUserProfile(); diff --git a/packages/core/src/layout/Sidebar/Settings/ThemeToggle.tsx b/packages/core/src/layout/Sidebar/Settings/ThemeToggle.tsx index 29cfb24885..a5e703089c 100644 --- a/packages/core/src/layout/Sidebar/Settings/ThemeToggle.tsx +++ b/packages/core/src/layout/Sidebar/Settings/ThemeToggle.tsx @@ -37,7 +37,7 @@ export const SidebarThemeToggle = () => { ); const themeIds = appThemeApi.getInstalledThemes(); - // TODO: can these be put on the theme itself? + // TODO(marcuseide): can these be put on the theme itself? const themeIcons = { dark: , light: , diff --git a/packages/core/src/layout/Sidebar/Settings/UserSettings.tsx b/packages/core/src/layout/Sidebar/Settings/UserSettings.tsx index 8f541364ff..85dbefff9b 100644 --- a/packages/core/src/layout/Sidebar/Settings/UserSettings.tsx +++ b/packages/core/src/layout/Sidebar/Settings/UserSettings.tsx @@ -22,11 +22,11 @@ import { SidebarItem } from '../Items'; import { useUserProfile } from './useUserProfileInfo'; import { SidebarContext } from '../config'; -export const SidebarUserSettings = ({ - providerSettings, -}: { +type Props = { providerSettings?: React.ReactNode; -}) => { +}; + +export const SidebarUserSettings = ({ providerSettings }: Props) => { const { isOpen: sidebarOpen } = useContext(SidebarContext); const { displayName } = useUserProfile(); const [open, setOpen] = React.useState(false); @@ -44,7 +44,6 @@ export const SidebarUserSettings = ({ setOpen(false); }; - // Close the provider list when sidebar collapse useEffect(() => { if (!sidebarOpen && open) setOpen(false); }, [open, sidebarOpen]); From 12e2d169f8b547d86a0890e4dbe7720ffc52ded9 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Fri, 11 Sep 2020 09:59:53 +0200 Subject: [PATCH 04/11] Add featureflags components and toggle method on api --- packages/core-api/src/app/FeatureFlags.tsx | 7 ++ .../Sidebar/Settings/FeatureFlagsItem.tsx | 67 +++++++++++++++++++ .../Sidebar/Settings/FeatureFlagsList.tsx | 38 +++++++++++ 3 files changed, 112 insertions(+) create mode 100644 packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx create mode 100644 packages/core/src/layout/Sidebar/Settings/FeatureFlagsList.tsx diff --git a/packages/core-api/src/app/FeatureFlags.tsx b/packages/core-api/src/app/FeatureFlags.tsx index 11c084d3ed..79c3e5d6af 100644 --- a/packages/core-api/src/app/FeatureFlags.tsx +++ b/packages/core-api/src/app/FeatureFlags.tsx @@ -80,6 +80,13 @@ export class UserFlags extends Map { return output; } + toggle(name: FeatureFlagName): FeatureFlagState { + Boolean(super.get(name)) + ? super.set(name, FeatureFlagState.Off) + : super.set(name, FeatureFlagState.On); + return super.get(name) || FeatureFlagState.Off; + } + delete(name: FeatureFlagName): boolean { const output = super.delete(name); this.save(); diff --git a/packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx new file mode 100644 index 0000000000..d7da3afbe6 --- /dev/null +++ b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx @@ -0,0 +1,67 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { FeatureFlagName, FeatureFlagsApi } from '@backstage/core-api'; +import { + ListItem, + ListItemSecondaryAction, + ListItemText, + Tooltip, +} from '@material-ui/core'; +import CheckIcon from '@material-ui/icons/CheckCircle'; +import { ToggleButton } from '@material-ui/lab'; + +type Props = { + featureFlag: { name: FeatureFlagName; pluginId: string }; + api: FeatureFlagsApi; +}; + +export const FlagItem = ({ featureFlag, api }: Props) => { + const [enabled, setEnabled] = React.useState( + Boolean(api.getFlags().get(featureFlag.name)), + ); + + const toggleFlag = () => { + const newState = api.getFlags().toggle(featureFlag.name); + setEnabled(Boolean(newState)); + }; + + return ( + + + + + + + + + + + ); +}; diff --git a/packages/core/src/layout/Sidebar/Settings/FeatureFlagsList.tsx b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsList.tsx new file mode 100644 index 0000000000..13e3a28c35 --- /dev/null +++ b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsList.tsx @@ -0,0 +1,38 @@ +/* + * Copyright 2020 Spotify AB + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import List from '@material-ui/core/List'; +import ListSubheader from '@material-ui/core/ListSubheader'; +import { useApi, featureFlagsApiRef } from '@backstage/core-api'; +import { FlagItem } from './FeatureFlagsItem'; + +export const FeatureFlagsList = () => { + const featureFlagsApi = useApi(featureFlagsApiRef); + const featureFlags = featureFlagsApi.getRegisteredFlags(); + + return ( + Feature Flags}> + {featureFlags.map(featureFlag => ( + + ))} + + ); +}; From f01596d8c45ae54ad35a5afe5aba48353b619a95 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Fri, 11 Sep 2020 10:07:48 +0200 Subject: [PATCH 05/11] Update sidepar --- packages/app/src/components/Root/Root.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/app/src/components/Root/Root.tsx b/packages/app/src/components/Root/Root.tsx index e91504d619..03e24cf4ae 100644 --- a/packages/app/src/components/Root/Root.tsx +++ b/packages/app/src/components/Root/Root.tsx @@ -35,8 +35,6 @@ import { SidebarSearchField, SidebarSpace, SidebarUserSettings, - SidebarThemeToggle, - SidebarPinButton, DefaultProviderSettings, } from '@backstage/core'; import { NavLink } from 'react-router-dom'; @@ -103,9 +101,7 @@ const Root: FC<{}> = ({ children }) => ( /> - } /> - {children} From c8292fa05c4f6932dcf8a2d3269e9ef8f8bb56e2 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Fri, 11 Sep 2020 10:46:47 +0200 Subject: [PATCH 06/11] Change logic of FeatureFlags.toggle() --- packages/core-api/src/app/FeatureFlags.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/core-api/src/app/FeatureFlags.tsx b/packages/core-api/src/app/FeatureFlags.tsx index 79c3e5d6af..3db2a18a02 100644 --- a/packages/core-api/src/app/FeatureFlags.tsx +++ b/packages/core-api/src/app/FeatureFlags.tsx @@ -81,9 +81,11 @@ export class UserFlags extends Map { } toggle(name: FeatureFlagName): FeatureFlagState { - Boolean(super.get(name)) - ? super.set(name, FeatureFlagState.Off) - : super.set(name, FeatureFlagState.On); + if (super.get(name) === FeatureFlagState.On) { + super.set(name, FeatureFlagState.Off); + } else { + super.set(name, FeatureFlagState.On); + } return super.get(name) || FeatureFlagState.Off; } From 88fa72f91f7c8e9da2b92e5e04caeb6f775c6c95 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Fri, 11 Sep 2020 10:58:37 +0200 Subject: [PATCH 07/11] Handle empty sections --- .../Sidebar/Settings/AuthProviderList.tsx | 20 ++++++++++---- .../Sidebar/Settings/FeatureFlagsList.tsx | 26 ++++++++++++------- .../Sidebar/Settings/SettingsDialog.tsx | 11 +------- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/packages/core/src/layout/Sidebar/Settings/AuthProviderList.tsx b/packages/core/src/layout/Sidebar/Settings/AuthProviderList.tsx index 5d13d61148..50832da681 100644 --- a/packages/core/src/layout/Sidebar/Settings/AuthProviderList.tsx +++ b/packages/core/src/layout/Sidebar/Settings/AuthProviderList.tsx @@ -17,13 +17,23 @@ import React from 'react'; import List from '@material-ui/core/List'; import ListSubheader from '@material-ui/core/ListSubheader'; +import { Divider } from '@material-ui/core'; type Props = { providerSettings?: React.ReactNode; }; -export const AuthProvidersList = ({ providerSettings }: Props) => ( - Available Auth Providers}> - {providerSettings} - -); +export const AuthProvidersList = ({ providerSettings }: Props) => { + if (!providerSettings) { + return null; + } + + return ( + <> + + Available Auth Providers}> + {providerSettings} + + + ); +}; diff --git a/packages/core/src/layout/Sidebar/Settings/FeatureFlagsList.tsx b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsList.tsx index 13e3a28c35..d74a501c13 100644 --- a/packages/core/src/layout/Sidebar/Settings/FeatureFlagsList.tsx +++ b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsList.tsx @@ -19,20 +19,28 @@ import List from '@material-ui/core/List'; import ListSubheader from '@material-ui/core/ListSubheader'; import { useApi, featureFlagsApiRef } from '@backstage/core-api'; import { FlagItem } from './FeatureFlagsItem'; +import { Divider } from '@material-ui/core'; export const FeatureFlagsList = () => { const featureFlagsApi = useApi(featureFlagsApiRef); const featureFlags = featureFlagsApi.getRegisteredFlags(); + if (featureFlags.length === 0) { + return null; + } + return ( - Feature Flags}> - {featureFlags.map(featureFlag => ( - - ))} - + <> + + Feature Flags}> + {featureFlags.map(featureFlag => ( + + ))} + + ); }; diff --git a/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx b/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx index ee2f0bdfb4..9c452982e3 100644 --- a/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx +++ b/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx @@ -15,13 +15,7 @@ */ import React from 'react'; -import { - Card, - CardContent, - CardHeader, - Divider, - makeStyles, -} from '@material-ui/core'; +import { Card, CardContent, CardHeader, makeStyles } from '@material-ui/core'; import { AppSettingsList } from './AppSettingsList'; import { AuthProvidersList } from './AuthProviderList'; import { FeatureFlagsList } from './FeatureFlagsList'; @@ -52,11 +46,8 @@ export const SettingsDialog = ({ providerSettings }: Props) => { subheader={profile.email} /> - - - From e9c59b773e901804d623654e083d01709e84c6a2 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Fri, 11 Sep 2020 11:00:35 +0200 Subject: [PATCH 08/11] Update default-app template --- .../templates/default-app/packages/app/src/sidebar.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/create-app/templates/default-app/packages/app/src/sidebar.tsx b/packages/create-app/templates/default-app/packages/app/src/sidebar.tsx index 96d18965ec..9dd9ea64c3 100644 --- a/packages/create-app/templates/default-app/packages/app/src/sidebar.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/sidebar.tsx @@ -18,8 +18,6 @@ import { SidebarContext, SidebarSpace, SidebarUserSettings, - SidebarThemeToggle, - SidebarPinButton, DefaultProviderSettings, } from '@backstage/core'; @@ -39,9 +37,7 @@ export const AppSidebar = () => ( - } /> - ); From fd83d501db3530039ab5c494f92797cca8fe7a18 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Thu, 17 Sep 2020 13:36:12 +0200 Subject: [PATCH 09/11] Remove unnecessary boolean conversion --- .../core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx index d7da3afbe6..21074a5153 100644 --- a/packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx +++ b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx @@ -53,11 +53,7 @@ export const FlagItem = ({ featureFlag, api }: Props) => { selected={enabled} onChange={toggleFlag} > - + From b67b2b6c0a4e543956ae75213ee9953145b34634 Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Thu, 17 Sep 2020 13:37:29 +0200 Subject: [PATCH 10/11] Remove commented out code --- packages/core/src/layout/Sidebar/Settings/index.ts | 1 - packages/core/src/layout/Sidebar/index.ts | 4 ---- 2 files changed, 5 deletions(-) diff --git a/packages/core/src/layout/Sidebar/Settings/index.ts b/packages/core/src/layout/Sidebar/Settings/index.ts index 5479236a3b..7abf061620 100644 --- a/packages/core/src/layout/Sidebar/Settings/index.ts +++ b/packages/core/src/layout/Sidebar/Settings/index.ts @@ -17,5 +17,4 @@ export { ProviderSettingsItem } from './ProviderSettingsItem'; export { OAuthProviderSettings } from './OAuthProviderSettings'; export { OIDCProviderSettings } from './OIDCProviderSettings'; -// export { UserProfile } from './UserProfile'; export { SidebarUserSettings } from './UserSettings'; diff --git a/packages/core/src/layout/Sidebar/index.ts b/packages/core/src/layout/Sidebar/index.ts index fb9a457dea..a644c06e14 100644 --- a/packages/core/src/layout/Sidebar/index.ts +++ b/packages/core/src/layout/Sidebar/index.ts @@ -25,15 +25,11 @@ export { SidebarSpacer, } from './Items'; export { IntroCard, SidebarIntro } from './Intro'; -// export { SidebarPinButton } from './PinButton'; export { SIDEBAR_INTRO_LOCAL_STORAGE, SidebarContext, sidebarConfig, } from './config'; export type { SidebarContextType } from './config'; -// export { SidebarThemeToggle } from './SidebarThemeToggle'; -// export { SidebarUserSettings } from './UserSettings'; export { DefaultProviderSettings } from './DefaultProviderSettings'; export * from './Settings'; -// export { SidebarUserSettings } from './UserSettings'; From 3664ef13c2752ca8c11cf388da633bb8fbd42e3f Mon Sep 17 00:00:00 2001 From: Marcus Eide Date: Thu, 17 Sep 2020 13:53:57 +0200 Subject: [PATCH 11/11] Pass props to lists and control rendering from outside wrapper --- .../Sidebar/Settings/AuthProviderList.tsx | 22 ++++-------- .../Sidebar/Settings/FeatureFlagsItem.tsx | 20 ++++++++--- .../Sidebar/Settings/FeatureFlagsList.tsx | 36 ++++++------------- .../Sidebar/Settings/SettingsDialog.tsx | 25 +++++++++++-- 4 files changed, 54 insertions(+), 49 deletions(-) diff --git a/packages/core/src/layout/Sidebar/Settings/AuthProviderList.tsx b/packages/core/src/layout/Sidebar/Settings/AuthProviderList.tsx index 50832da681..34cf6fb837 100644 --- a/packages/core/src/layout/Sidebar/Settings/AuthProviderList.tsx +++ b/packages/core/src/layout/Sidebar/Settings/AuthProviderList.tsx @@ -17,23 +17,13 @@ import React from 'react'; import List from '@material-ui/core/List'; import ListSubheader from '@material-ui/core/ListSubheader'; -import { Divider } from '@material-ui/core'; type Props = { - providerSettings?: React.ReactNode; + providerSettings: React.ReactNode; }; -export const AuthProvidersList = ({ providerSettings }: Props) => { - if (!providerSettings) { - return null; - } - - return ( - <> - - Available Auth Providers}> - {providerSettings} - - - ); -}; +export const AuthProvidersList = ({ providerSettings }: Props) => ( + Available Auth Providers}> + {providerSettings} + +); diff --git a/packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx index 21074a5153..3e40ce69cc 100644 --- a/packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx +++ b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx @@ -15,7 +15,11 @@ */ import React from 'react'; -import { FeatureFlagName, FeatureFlagsApi } from '@backstage/core-api'; +import { + FeatureFlagName, + useApi, + featureFlagsApiRef, +} from '@backstage/core-api'; import { ListItem, ListItemSecondaryAction, @@ -25,12 +29,18 @@ import { import CheckIcon from '@material-ui/icons/CheckCircle'; import { ToggleButton } from '@material-ui/lab'; -type Props = { - featureFlag: { name: FeatureFlagName; pluginId: string }; - api: FeatureFlagsApi; +export type Item = { + name: FeatureFlagName; + pluginId: string; }; -export const FlagItem = ({ featureFlag, api }: Props) => { +type Props = { + featureFlag: Item; +}; + +export const FlagItem = ({ featureFlag }: Props) => { + const api = useApi(featureFlagsApiRef); + const [enabled, setEnabled] = React.useState( Boolean(api.getFlags().get(featureFlag.name)), ); diff --git a/packages/core/src/layout/Sidebar/Settings/FeatureFlagsList.tsx b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsList.tsx index d74a501c13..5687446511 100644 --- a/packages/core/src/layout/Sidebar/Settings/FeatureFlagsList.tsx +++ b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsList.tsx @@ -17,30 +17,16 @@ import React from 'react'; import List from '@material-ui/core/List'; import ListSubheader from '@material-ui/core/ListSubheader'; -import { useApi, featureFlagsApiRef } from '@backstage/core-api'; -import { FlagItem } from './FeatureFlagsItem'; -import { Divider } from '@material-ui/core'; +import { FlagItem, Item } from './FeatureFlagsItem'; -export const FeatureFlagsList = () => { - const featureFlagsApi = useApi(featureFlagsApiRef); - const featureFlags = featureFlagsApi.getRegisteredFlags(); - - if (featureFlags.length === 0) { - return null; - } - - return ( - <> - - Feature Flags}> - {featureFlags.map(featureFlag => ( - - ))} - - - ); +type Props = { + featureFlags: Item[]; }; + +export const FeatureFlagsList = ({ featureFlags }: Props) => ( + Feature Flags}> + {featureFlags.map(featureFlag => ( + + ))} + +); diff --git a/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx b/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx index 9c452982e3..71c4899862 100644 --- a/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx +++ b/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx @@ -15,13 +15,20 @@ */ import React from 'react'; -import { Card, CardContent, CardHeader, makeStyles } from '@material-ui/core'; +import { + Card, + CardContent, + CardHeader, + makeStyles, + Divider, +} from '@material-ui/core'; import { AppSettingsList } from './AppSettingsList'; import { AuthProvidersList } from './AuthProviderList'; import { FeatureFlagsList } from './FeatureFlagsList'; import { SignInAvatar } from './SignInAvatar'; import { UserSettingsMenu } from './UserSettingsMenu'; import { useUserProfile } from './useUserProfileInfo'; +import { useApi, featureFlagsApiRef } from '@backstage/core-api'; const useStyles = makeStyles({ root: { @@ -36,6 +43,8 @@ type Props = { export const SettingsDialog = ({ providerSettings }: Props) => { const classes = useStyles(); const { profile, displayName } = useUserProfile(); + const featureFlagsApi = useApi(featureFlagsApiRef); + const featureFlags = featureFlagsApi.getRegisteredFlags(); return ( @@ -47,8 +56,18 @@ export const SettingsDialog = ({ providerSettings }: Props) => { /> - - + {providerSettings && ( + <> + + + + )} + {featureFlags.length > 0 && ( + <> + + + + )} );