List auth providers in UserSettings

This commit is contained in:
Marcus Eide
2020-06-08 16:45:43 +02:00
parent 235007d295
commit eea242f14f
+125 -23
View File
@@ -1,32 +1,110 @@
/*
* 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, { useState, useContext, useEffect, useRef } from 'react';
import Collapse from '@material-ui/core/Collapse';
import ExpandLess from '@material-ui/icons/ExpandLess';
import ExpandMore from '@material-ui/icons/ExpandMore';
import StarBorder from '@material-ui/icons/StarBorder';
import Star from '@material-ui/icons/Star';
import { SidebarContext } from './config';
import { SidebarItem, SidebarDivider } from './Items';
import { SidebarItem } from './Items';
import AccountCircleIcon from '@material-ui/icons/AccountCircle';
import Divider from '@material-ui/core/Divider';
import { useApi, googleAuthApiRef, ProfileInfo } from '@backstage/core-api';
import { Avatar, IconButton } from '@material-ui/core';
import {
useApi,
googleAuthApiRef,
githubAuthApiRef,
ProfileInfo,
} from '@backstage/core-api';
import { Avatar, IconButton, makeStyles, Tooltip } from '@material-ui/core';
import PowerButton from '@material-ui/icons/PowerSettingsNew';
import { SidebarThemeToggle } from './SidebarThemeToggle';
// import { SidebarThemeToggle } from './SidebarThemeToggle';
type Provider = {
title: string;
api: any;
identity?: boolean;
isSignedIn: boolean;
icon: any;
};
const useProviders = () => {
const googleAuth = useApi(googleAuthApiRef);
const githubAuth = useApi(githubAuthApiRef);
const [providers, setProviders] = useState<Provider[]>([
{
title: 'Google',
api: googleAuth,
identity: true,
isSignedIn: false,
icon: Star,
},
{
title: 'Github',
api: githubAuth,
isSignedIn: false,
icon: StarBorder,
},
]);
Promise.all(
providers.map((provider: Provider) =>
provider.identity
? provider.api.getIdToken({ optional: true })
: provider.api.getAccessToken('', { optional: true }),
),
).then(results => {
results.map((result, i) => {
providers[i].isSignedIn = !!result;
});
setProviders(providers);
});
return providers;
};
const useStyles = makeStyles({
avatar: {
width: 24,
height: 24,
},
});
export function SidebarUserSettings() {
const { isOpen: sidebarOpen } = useContext(SidebarContext);
const [open, setOpen] = React.useState(false);
const ref = useRef<Element>(); // for scrolling down when collapse item opens
const googleAuth = useApi(googleAuthApiRef);
const providers = useProviders();
const [profile, setProfile] = useState<ProfileInfo>();
const classes = useStyles();
// TODO(soapraj): List all the providers supported by the app and let user log in from here
// TODO(soapraj): How to observe if the user is logged in
useEffect(() => {
googleAuth.getProfile({ optional: true }).then(googleProfile => {
setProfile(googleProfile);
});
}, [googleAuth, open]);
const identityProvider = providers.find(
(provider: Provider) => provider.identity,
);
identityProvider?.api
.getProfile({ optional: true })
.then((userProfile: ProfileInfo) => {
setProfile(userProfile);
});
}, [providers, open]);
const handleClick = () => {
setOpen(!open);
@@ -36,13 +114,12 @@ export function SidebarUserSettings() {
// Close the provider list when sidebar collapse
useEffect(() => {
if (!sidebarOpen && open) setOpen(false);
}, [sidebarOpen]);
}, [open, sidebarOpen]);
// Handle main auth info that is shown on the collapsible SidebarItem
let avatar;
let displayName;
if (profile) {
// const classes = useStyles();
const email = profile.email;
const name = profile.name;
const imageUrl = profile.picture;
@@ -52,8 +129,12 @@ export function SidebarUserSettings() {
emailTrimmed.charAt(0).toUpperCase() + emailTrimmed.slice(1);
displayName = name ?? displayEmail;
avatar = imageUrl
? () => <Avatar alt={name} src={imageUrl} />
: () => <Avatar alt={name}>{avatarFallback[0]}</Avatar>;
? () => <Avatar alt={name} src={imageUrl} className={classes.avatar} />
: () => (
<Avatar alt={name} className={classes.avatar}>
{avatarFallback[0]}
</Avatar>
);
}
return (
@@ -65,18 +146,39 @@ export function SidebarUserSettings() {
icon={avatar || AccountCircleIcon}
disableSelected
>
{open ? <ExpandMore /> : <ExpandLess />}
{open ? <ExpandLess /> : <ExpandMore />}
</SidebarItem>
<Collapse in={open} timeout="auto" unmountOnExit>
<SidebarItem text="Google" icon={StarBorder} disableSelected>
<IconButton
onClick={() =>
profile ? googleAuth.logout() : googleAuth.getAccessToken()
}
{providers.map((provider: Provider) => (
<SidebarItem
key={provider.title}
text={provider.title}
icon={provider.icon ?? StarBorder}
disableSelected
>
<PowerButton color={profile ? 'primary' : 'disabled'} />
</IconButton>
</SidebarItem>
<IconButton
onClick={() =>
provider.isSignedIn
? provider.api.logout()
: provider.api.getAccessToken()
}
>
<Tooltip
placement="top"
arrow
title={
provider.isSignedIn
? `Logout from ${provider.title}`
: `Sign in to ${provider.title}`
}
>
<PowerButton
color={provider.isSignedIn ? 'secondary' : 'primary'}
/>
</Tooltip>
</IconButton>
</SidebarItem>
))}
</Collapse>
</>
);