diff --git a/packages/app/src/components/Root/Root.tsx b/packages/app/src/components/Root/Root.tsx
index 579b88053f..0e30c15254 100644
--- a/packages/app/src/components/Root/Root.tsx
+++ b/packages/app/src/components/Root/Root.tsx
@@ -31,8 +31,9 @@ import {
SidebarDivider,
SidebarSearchField,
SidebarSpace,
- SidebarUserBadge,
+ SidebarUserSettings,
SidebarThemeToggle,
+ SidebarPinButton,
} from '@backstage/core';
import { NavLink } from 'react-router-dom';
@@ -90,7 +91,8 @@ const Root: FC<{}> = ({ children }) => (
-
+
+
{children}
diff --git a/packages/core/src/layout/Sidebar/Items.tsx b/packages/core/src/layout/Sidebar/Items.tsx
index ddd71cc189..0a875c9035 100644
--- a/packages/core/src/layout/Sidebar/Items.tsx
+++ b/packages/core/src/layout/Sidebar/Items.tsx
@@ -59,6 +59,7 @@ const useStyles = makeStyles(theme => {
fontWeight: 'bold',
whiteSpace: 'nowrap',
lineHeight: 1.0,
+ flex: '3 1 auto',
},
iconContainer: {
boxSizing: 'border-box',
@@ -84,6 +85,11 @@ const useStyles = makeStyles(theme => {
searchContainer: {
width: drawerWidthOpen - iconContainerWidth,
},
+ secondaryAction: {
+ width: theme.spacing(6),
+ textAlign: 'center',
+ marginRight: theme.spacing(1),
+ },
selected: {
'&$root': {
borderLeft: `solid ${selectedIndicatorWidth}px #9BF0E1`,
@@ -148,7 +154,6 @@ export const SidebarItem: FC = ({
);
}
-
return (
= ({
{text}
)}
- {children}
+ {children}
);
};
diff --git a/packages/core/src/layout/Sidebar/LoggedUserBadge.tsx b/packages/core/src/layout/Sidebar/LoggedUserBadge.tsx
deleted file mode 100644
index d0c3dc62c2..0000000000
--- a/packages/core/src/layout/Sidebar/LoggedUserBadge.tsx
+++ /dev/null
@@ -1,298 +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, useState, useEffect } from 'react';
-import { makeStyles, Theme } from '@material-ui/core/styles';
-import { sidebarConfig } from './config';
-import {
- Avatar,
- ListItem,
- ListItemAvatar,
- ListItemText,
- Popover,
- List,
- ListItemIcon,
- ListItemSecondaryAction,
- IconButton,
- Tooltip,
- Typography,
-} from '@material-ui/core';
-import { blueGrey } from '@material-ui/core/colors';
-import { useSetState } from 'react-use';
-import { Skeleton } from '@material-ui/lab';
-import { useApi, googleAuthApiRef, ProfileInfo } from '@backstage/core-api';
-import LogoutIcon from '@material-ui/icons/PowerSettingsNew';
-import ControlPointIcon from '@material-ui/icons/ControlPoint';
-import AccountCircleIcon from '@material-ui/icons/AccountCircle';
-
-const useStyles = makeStyles(theme => {
- const { drawerWidthOpen, userBadgeDiameter } = sidebarConfig;
- return {
- root: {
- width: drawerWidthOpen,
- display: 'flex',
- alignItems: 'center',
- paddingLeft: 18,
- paddingTop: 14,
- paddingBottom: 14,
- color: '#b5b5b5',
- },
- avatar: {
- width: userBadgeDiameter,
- height: userBadgeDiameter,
- marginRight: 8,
- },
- purple: {
- color: theme.palette.getContrastText(blueGrey[500]),
- backgroundColor: blueGrey[500],
- },
- listItemText: {
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- },
- };
-});
-
-const SessionListItem: FC<{
- classes: any;
- loading: boolean;
- title: string;
- icon: any;
- user: any;
- onSignIn: Function;
- onSignOut: Function;
-}> = ({
- classes,
- loading,
- title,
- icon,
- user,
- onSignIn,
- onSignOut,
- ...props
-}) => {
- if (loading) {
- return (
-
-
-
-
- }
- secondary={}
- />
-
-
-
-
-
-
- );
- }
-
- // TODO: Not functional yet to sign in from the sidebar
- if (!user) {
- return (
-
- {icon}
-
-
-
- onSignIn()}>
-
-
-
-
-
- );
- }
-
- const { id, avatarUrl, avatarAlt } = user;
-
- return (
-
-
-
- {avatarAlt && avatarAlt[0].toUpperCase()}
-
-
-
- {id}
-
- }
- secondary={title}
- />
-
-
- onSignOut()}>
-
-
-
-
-
- );
-};
-
-const useGoogleLoginState = (open: boolean) => {
- const googleAuth = useApi(googleAuthApiRef);
- const [loading, setLoading] = useState(true);
- const [profile, setProfile] = useState();
-
- useEffect(() => {
- let didCancel = false;
-
- if (open) {
- googleAuth.getProfile().then(_profile => {
- if (!didCancel) {
- setProfile(_profile);
- setLoading(false);
- }
- });
- }
-
- return () => {
- didCancel = true;
- };
- }, [open, googleAuth]);
-
- if (loading) {
- return { loading: true };
- }
- return { loading: false, isLoggedIn: !!profile, profile };
-};
-
-type Props = {
- email: string;
- imageUrl?: string;
- name?: string;
- collapsedMode?: boolean;
-};
-
-export const LoggedUserBadge: FC = ({
- imageUrl,
- name,
- email,
- collapsedMode = false,
-}) => {
- const [state, setState] = useSetState({
- open: false,
- anchorEl: null,
- });
- const googleAuth = useApi(googleAuthApiRef);
- const googleLogin = useGoogleLoginState(state.open);
-
- const handleOpen = (event: {
- preventDefault: () => void;
- currentTarget: any;
- }) => {
- // This prevents ghost click.
- event.preventDefault();
- setState({
- open: true,
- anchorEl: event.currentTarget,
- });
- };
-
- const handleClose = () => {
- setState({
- open: false,
- });
- };
-
- const handleGoogleSignIn = () => {
- googleAuth.getIdToken();
- handleClose();
- };
-
- const handleGoogleSignOut = () => {
- googleAuth.logout();
- };
-
- const classes = useStyles();
- const avatarFallback = email.charAt(0).toUpperCase() + email.slice(1);
- const emailTrimmed = email.split('@')[0];
- const displayEmail =
- emailTrimmed.charAt(0).toUpperCase() + emailTrimmed.slice(1);
- const displayName = name ?? displayEmail;
-
- return (
- <>
-
-
-
- {imageUrl ? (
-
- ) : (
-
- {avatarFallback[0]}
-
- )}
-
- {!collapsedMode && (
-
- {displayName}
-
- }
- />
- )}
-
-
-
-
-
-
-
- >
- );
-};
diff --git a/packages/core/src/layout/Sidebar/UserBadge.tsx b/packages/core/src/layout/Sidebar/PinButton.tsx
similarity index 61%
rename from packages/core/src/layout/Sidebar/UserBadge.tsx
rename to packages/core/src/layout/Sidebar/PinButton.tsx
index d3e02d26cc..8c52eeb24d 100644
--- a/packages/core/src/layout/Sidebar/UserBadge.tsx
+++ b/packages/core/src/layout/Sidebar/PinButton.tsx
@@ -14,35 +14,32 @@
* limitations under the License.
*/
-import React, { FC, useContext, useEffect, useState } from 'react';
+import React, { FC, useContext } from 'react';
import { makeStyles } from '@material-ui/core';
-import AccountCircleIcon from '@material-ui/icons/AccountCircle';
-import { SidebarContext } from './config';
-import { SidebarItem } from './Items';
-import { LoggedUserBadge } from './LoggedUserBadge';
import DoubleArrowIcon from '@material-ui/icons/DoubleArrow';
+import { SidebarContext } from './config';
import { BackstageTheme } from '@backstage/theme';
import { SidebarPinStateContext } from './Page';
-import { useApi, googleAuthApiRef, ProfileInfo } from '@backstage/core-api';
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: `calc(50% - ${ARROW_BUTTON_SIZE / 2}px)`,
+ top: -(theme.spacing(6) + ARROW_BUTTON_SIZE) / 2,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '2px 0px 0px 2px',
- background: theme.palette.pinSidebarButton.icon,
- color: theme.palette.pinSidebarButton.background,
+ background: theme.palette.pinSidebarButton.background,
+ color: theme.palette.pinSidebarButton.icon,
border: 'none',
outline: 'none',
cursor: 'pointer',
@@ -53,37 +50,15 @@ const useStyles = makeStyles(theme => {
};
});
-export const SidebarUserBadge: FC<{}> = () => {
+export const SidebarPinButton: FC<{}> = () => {
const { isOpen } = useContext(SidebarContext);
const { isPinned, toggleSidebarPinState } = useContext(
SidebarPinStateContext,
);
const classes = useStyles({ isPinned });
- const googleAuth = useApi(googleAuthApiRef);
- const [profile, setProfile] = useState();
-
- useEffect(() => {
- // TODO(soapraj): How to observe if the user is logged in
- // TODO(soapraj): List all the providers supported by the app and let user log in from here
- googleAuth.getProfile({ optional: true }).then(googleProfile => {
- setProfile(googleProfile);
- });
- }, [googleAuth]);
return (
- {profile ? (
- <>
-
- >
- ) : (
-
- )}
{isOpen && (