Use TabbedCard to tab between different setting categories
This commit is contained in:
@@ -14,12 +14,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import { List, ListSubheader } from '@material-ui/core';
|
||||
import { List } from '@material-ui/core';
|
||||
import { SidebarThemeToggle } from './ThemeToggle';
|
||||
import { SidebarPinButton } from './PinButton';
|
||||
|
||||
export const AppSettingsList = () => (
|
||||
<List dense subheader={<ListSubheader>App Settings</ListSubheader>}>
|
||||
<List dense>
|
||||
<SidebarThemeToggle />
|
||||
<SidebarPinButton />
|
||||
</List>
|
||||
|
||||
@@ -15,14 +15,12 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { List, ListSubheader } from '@material-ui/core';
|
||||
import { List } from '@material-ui/core';
|
||||
|
||||
type Props = {
|
||||
providers: React.ReactNode;
|
||||
};
|
||||
|
||||
export const AuthProvidersList = ({ providers }: Props) => (
|
||||
<List subheader={<ListSubheader>Available Auth Providers</ListSubheader>}>
|
||||
{providers}
|
||||
</List>
|
||||
<List dense>{providers}</List>
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { List, ListSubheader } from '@material-ui/core';
|
||||
import { List } from '@material-ui/core';
|
||||
import {
|
||||
useApi,
|
||||
featureFlagsApiRef,
|
||||
@@ -54,7 +54,7 @@ export const FeatureFlagsList = ({ featureFlags }: Props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<List dense subheader={<ListSubheader>Feature Flags</ListSubheader>}>
|
||||
<List dense>
|
||||
{featureFlags.map(featureFlag => {
|
||||
const enabled = Boolean(state[featureFlag.name]);
|
||||
|
||||
|
||||
@@ -14,13 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import React, { ChangeEvent, RefObject, useEffect, useState } from 'react';
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardHeader,
|
||||
makeStyles,
|
||||
Divider,
|
||||
PopoverActions,
|
||||
} from '@material-ui/core';
|
||||
import { AppSettingsList } from './AppSettingsList';
|
||||
import { AuthProvidersList } from './AuthProviderList';
|
||||
@@ -28,28 +28,53 @@ import { FeatureFlagsList } from './FeatureFlagsList';
|
||||
import { SignInAvatar } from './SignInAvatar';
|
||||
import { UserSettingsMenu } from './UserSettingsMenu';
|
||||
import { useUserProfile } from './useUserProfileInfo';
|
||||
import { useApi, featureFlagsApiRef } from '@backstage/core';
|
||||
import {
|
||||
useApi,
|
||||
featureFlagsApiRef,
|
||||
TabbedCard,
|
||||
CardTab,
|
||||
InfoCard,
|
||||
} from '@backstage/core';
|
||||
import { ConfiguredProviderSettings } from './ConfiguredProviderSettings';
|
||||
import { ProviderSettings } from './UserSettings';
|
||||
import { Alert } from '@material-ui/lab';
|
||||
|
||||
const useStyles = makeStyles({
|
||||
root: {
|
||||
minWidth: 400,
|
||||
maxWidth: 500,
|
||||
},
|
||||
});
|
||||
|
||||
type Props = {
|
||||
popoverActionRef: RefObject<PopoverActions | null>;
|
||||
providerSettings?: ProviderSettings;
|
||||
};
|
||||
|
||||
export const SettingsDialog = ({ providerSettings }: Props) => {
|
||||
export const SettingsDialog = ({
|
||||
popoverActionRef,
|
||||
providerSettings,
|
||||
}: Props) => {
|
||||
const classes = useStyles();
|
||||
const { profile, displayName } = useUserProfile();
|
||||
const featureFlagsApi = useApi(featureFlagsApiRef);
|
||||
const featureFlags = featureFlagsApi.getRegisteredFlags();
|
||||
const [selectedTab, setSelectedTab] = useState<string | number>('auth');
|
||||
|
||||
const providers = providerSettings ?? <ConfiguredProviderSettings />;
|
||||
|
||||
const handleChange = (
|
||||
_ev: ChangeEvent<{}>,
|
||||
newSelectedTab: string | number,
|
||||
) => {
|
||||
setSelectedTab(newSelectedTab);
|
||||
};
|
||||
|
||||
// Update the position of the popover to handle different heights
|
||||
useEffect(() => {
|
||||
popoverActionRef?.current?.updatePosition();
|
||||
}, [selectedTab, popoverActionRef]);
|
||||
|
||||
return (
|
||||
<Card className={classes.root}>
|
||||
<CardHeader
|
||||
@@ -59,15 +84,34 @@ export const SettingsDialog = ({ providerSettings }: Props) => {
|
||||
subheader={profile.email}
|
||||
/>
|
||||
<CardContent>
|
||||
<AppSettingsList />
|
||||
<Divider />
|
||||
<AuthProvidersList providers={providers} />
|
||||
{featureFlags.length > 0 && (
|
||||
<>
|
||||
<Divider />
|
||||
<FeatureFlagsList featureFlags={featureFlags} />
|
||||
</>
|
||||
)}
|
||||
<InfoCard
|
||||
title="App Settings"
|
||||
subheader="General settings related to how the app feels and looks"
|
||||
variant="flat"
|
||||
noPadding
|
||||
>
|
||||
<AppSettingsList />
|
||||
</InfoCard>
|
||||
<TabbedCard
|
||||
title="Additional Settings"
|
||||
subheader="Settings that are specific to a plugin, or feature of the app"
|
||||
variant="flat"
|
||||
value={selectedTab}
|
||||
onChange={handleChange}
|
||||
noPadding
|
||||
>
|
||||
<CardTab value="auth" label="Auth Providers">
|
||||
<AuthProvidersList providers={providers} />
|
||||
</CardTab>
|
||||
<CardTab value="flags" label="Feature Flags">
|
||||
{featureFlags.length > 0 ? (
|
||||
<FeatureFlagsList featureFlags={featureFlags} />
|
||||
) : (
|
||||
// TODO(marcuseide): Replace with empty state component
|
||||
<Alert severity="info">No registered Feature Flags found</Alert>
|
||||
)}
|
||||
</CardTab>
|
||||
</TabbedCard>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
import React, { useEffect, useContext } from 'react';
|
||||
import { Popover } from '@material-ui/core';
|
||||
import { Popover, PopoverActions } from '@material-ui/core';
|
||||
import { SignInAvatar } from './SignInAvatar';
|
||||
import { SettingsDialog } from './SettingsDialog';
|
||||
import { SidebarItem, SidebarContext } from '@backstage/core';
|
||||
@@ -41,6 +41,7 @@ export const UserSettings = ({ providerSettings }: Props) => {
|
||||
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | undefined>(
|
||||
undefined,
|
||||
);
|
||||
const popoverActionRef = React.useRef<PopoverActions | null>(null);
|
||||
|
||||
const handleOpen = (event?: React.MouseEvent<HTMLButtonElement>) => {
|
||||
setAnchorEl(event?.currentTarget ?? undefined);
|
||||
@@ -66,6 +67,7 @@ export const UserSettings = ({ providerSettings }: Props) => {
|
||||
icon={SidebarAvatar}
|
||||
/>
|
||||
<Popover
|
||||
action={popoverActionRef}
|
||||
open={open}
|
||||
anchorEl={anchorEl}
|
||||
onClose={handleClose}
|
||||
@@ -78,7 +80,10 @@ export const UserSettings = ({ providerSettings }: Props) => {
|
||||
horizontal: 'left',
|
||||
}}
|
||||
>
|
||||
<SettingsDialog providerSettings={providerSettings} />
|
||||
<SettingsDialog
|
||||
popoverActionRef={popoverActionRef}
|
||||
providerSettings={providerSettings}
|
||||
/>
|
||||
</Popover>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user