diff --git a/.changeset/soft-falcons-love.md b/.changeset/soft-falcons-love.md new file mode 100644 index 0000000000..56ed193501 --- /dev/null +++ b/.changeset/soft-falcons-love.md @@ -0,0 +1,11 @@ +--- +'@backstage/plugin-user-settings': minor +--- + +**BREAKING**: The `apiRef` passed to `ProviderSettingsItem` now needs to +implement `ProfileInfoApi & SessionApi`, rather than just the latter. This is +unlikely to have an effect on most users though, since the builtin auth +providers generally implement both. + +Fixed settings page showing providers as logged out when the user is using more +than one provider, and displayed some additional login information. diff --git a/plugins/user-settings/api-report.md b/plugins/user-settings/api-report.md index 76eaed940e..c51d4f992a 100644 --- a/plugins/user-settings/api-report.md +++ b/plugins/user-settings/api-report.md @@ -16,6 +16,7 @@ import { IdentityApi } from '@backstage/core-plugin-api'; import { JsonValue } from '@backstage/types'; import { Observable } from '@backstage/types'; import { ProfileInfo } from '@backstage/core-plugin-api'; +import { ProfileInfoApi } from '@backstage/core-plugin-api'; import { PropsWithChildren } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; import { SessionApi } from '@backstage/core-plugin-api'; @@ -32,7 +33,7 @@ export const ProviderSettingsItem: (props: { title: string; description: string; icon: IconComponent; - apiRef: ApiRef; + apiRef: ApiRef; }) => JSX.Element; // @public (undocumented) diff --git a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsAvatar.tsx b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsAvatar.tsx new file mode 100644 index 0000000000..e92b0efe15 --- /dev/null +++ b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsAvatar.tsx @@ -0,0 +1,38 @@ +/* + * Copyright 2020 The Backstage Authors + * + * 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 { sidebarConfig } from '@backstage/core-components'; + +const useStyles = makeStyles(theme => ({ + avatar: { + width: ({ size }) => size, + height: ({ size }) => size, + fontSize: ({ size }) => size * 0.7, + border: `1px solid ${theme.palette.textSubtle}`, + }, +})); + +type Props = { size?: number; picture: string | undefined }; + +export const ProviderSettingsAvatar = ({ size, picture }: Props) => { + const { iconSize } = sidebarConfig; + const classes = useStyles(size ? { size } : { size: iconSize }); + + return ; +}; diff --git a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx index e170aa2daa..ab6ad8dff9 100644 --- a/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx +++ b/plugins/user-settings/src/components/AuthProviders/ProviderSettingsItem.tsx @@ -17,31 +17,38 @@ import React, { useEffect, useState } from 'react'; import { Button, + Grid, ListItem, ListItemIcon, ListItemSecondaryAction, ListItemText, Tooltip, + Typography, } from '@material-ui/core'; import { ApiRef, SessionApi, + SessionState, + ProfileInfoApi, + ProfileInfo, useApi, IconComponent, - SessionState, } from '@backstage/core-plugin-api'; +import { ProviderSettingsAvatar } from './ProviderSettingsAvatar'; /** @public */ export const ProviderSettingsItem = (props: { title: string; description: string; icon: IconComponent; - apiRef: ApiRef; + apiRef: ApiRef; }) => { const { title, description, icon: Icon, apiRef } = props; const api = useApi(apiRef); const [signedIn, setSignedIn] = useState(false); + const emptyProfile: ProfileInfo = {}; + const [profile, setProfile] = useState(emptyProfile); useEffect(() => { let didCancel = false; @@ -50,7 +57,18 @@ export const ProviderSettingsItem = (props: { .sessionState$() .subscribe((sessionState: SessionState) => { if (!didCancel) { - setSignedIn(sessionState === SessionState.SignedIn); + api + .getProfile({ optional: true }) + .then((profileResponse: ProfileInfo | undefined) => { + if (!didCancel) { + if (sessionState === SessionState.SignedIn) { + setSignedIn(true); + } + if (profileResponse) { + setProfile(profileResponse); + } + } + }); } }); @@ -69,7 +87,32 @@ export const ProviderSettingsItem = (props: { primary={title} secondary={ - {description} + + + + + + + + + + {profile.displayName} + + + {profile.email} + + + {description} + + + + + + } secondaryTypographyProps={{ noWrap: true, style: { width: '80%' } }}