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}
diff --git a/packages/core-api/src/app/FeatureFlags.tsx b/packages/core-api/src/app/FeatureFlags.tsx
index 11c084d3ed..3db2a18a02 100644
--- a/packages/core-api/src/app/FeatureFlags.tsx
+++ b/packages/core-api/src/app/FeatureFlags.tsx
@@ -80,6 +80,15 @@ export class UserFlags extends Map {
return output;
}
+ toggle(name: FeatureFlagName): FeatureFlagState {
+ if (super.get(name) === FeatureFlagState.On) {
+ super.set(name, FeatureFlagState.Off);
+ } else {
+ 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/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/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..34cf6fb837
--- /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/FeatureFlagsItem.tsx b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx
new file mode 100644
index 0000000000..3e40ce69cc
--- /dev/null
+++ b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsItem.tsx
@@ -0,0 +1,73 @@
+/*
+ * 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,
+ useApi,
+ featureFlagsApiRef,
+} 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';
+
+export type Item = {
+ name: FeatureFlagName;
+ pluginId: string;
+};
+
+type Props = {
+ featureFlag: Item;
+};
+
+export const FlagItem = ({ featureFlag }: Props) => {
+ const api = useApi(featureFlagsApiRef);
+
+ 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..5687446511
--- /dev/null
+++ b/packages/core/src/layout/Sidebar/Settings/FeatureFlagsList.tsx
@@ -0,0 +1,32 @@
+/*
+ * 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 { FlagItem, Item } from './FeatureFlagsItem';
+
+type Props = {
+ featureFlags: Item[];
+};
+
+export const FeatureFlagsList = ({ featureFlags }: Props) => (
+ Feature Flags}>
+ {featureFlags.map(featureFlag => (
+
+ ))}
+
+);
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..2727313ede
--- /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..71c4899862
--- /dev/null
+++ b/packages/core/src/layout/Sidebar/Settings/SettingsDialog.tsx
@@ -0,0 +1,74 @@
+/*
+ * 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,
+ 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: {
+ minWidth: 400,
+ },
+});
+
+type Props = {
+ providerSettings?: React.ReactNode;
+};
+
+export const SettingsDialog = ({ providerSettings }: Props) => {
+ const classes = useStyles();
+ const { profile, displayName } = useUserProfile();
+ const featureFlagsApi = useApi(featureFlagsApiRef);
+ const featureFlags = featureFlagsApi.getRegisteredFlags();
+
+ return (
+
+ }
+ action={}
+ title={displayName}
+ subheader={profile.email}
+ />
+
+
+ {providerSettings && (
+ <>
+
+
+ >
+ )}
+ {featureFlags.length > 0 && (
+ <>
+
+
+ >
+ )}
+
+
+ );
+};
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..f0430edfcf
--- /dev/null
+++ b/packages/core/src/layout/Sidebar/Settings/SignInAvatar.tsx
@@ -0,0 +1,42 @@
+/*
+ * 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';
+import { sidebarConfig } from '../config';
+
+const useStyles = makeStyles({
+ avatar: {
+ width: ({ size }) => size,
+ height: ({ size }) => size,
+ },
+});
+
+type Props = { size?: number };
+
+export const SignInAvatar = ({ size }: Props) => {
+ const { iconSize } = sidebarConfig;
+ const classes = useStyles(size ? { size } : { size: iconSize });
+ 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..a5e703089c
--- /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(marcuseide): 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..85dbefff9b
--- /dev/null
+++ b/packages/core/src/layout/Sidebar/Settings/UserSettings.tsx
@@ -0,0 +1,77 @@
+/*
+ * 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';
+
+type Props = {
+ providerSettings?: React.ReactNode;
+};
+
+export const SidebarUserSettings = ({ providerSettings }: Props) => {
+ 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);
+ };
+
+ 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 (
+ <>
+
+
+
+
+ >
+ );
+};
diff --git a/packages/core/src/layout/Sidebar/Settings/index.ts b/packages/core/src/layout/Sidebar/Settings/index.ts
index 6557ace53a..7abf061620 100644
--- a/packages/core/src/layout/Sidebar/Settings/index.ts
+++ b/packages/core/src/layout/Sidebar/Settings/index.ts
@@ -17,4 +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/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..a644c06e14 100644
--- a/packages/core/src/layout/Sidebar/index.ts
+++ b/packages/core/src/layout/Sidebar/index.ts
@@ -25,14 +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';
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 = () => (
- } />
-
);