userSetting plugin support i18n
Signed-off-by: mario ma <mario.ma.node@gmail.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-user-settings': patch
|
||||
---
|
||||
|
||||
userSetting plugin support i18n
|
||||
@@ -106,6 +106,16 @@ export const settingsNavItem: ExtensionDefinition<{
|
||||
export const userSettingsTranslationRef: TranslationRef<
|
||||
'user-settings',
|
||||
{
|
||||
readonly 'featureFlags.title': 'Feature Flags';
|
||||
readonly 'featureFlags.description': 'Please refresh the page when toggling feature flags';
|
||||
readonly 'featureFlags.emptyFlags.title': 'No Feature Flags';
|
||||
readonly 'featureFlags.emptyFlags.action.title': 'An example for how to add a feature flag is highlighted below:';
|
||||
readonly 'featureFlags.emptyFlags.action.readMoreButtonTitle': 'Read More';
|
||||
readonly 'featureFlags.emptyFlags.description': 'Feature Flags make it possible for plugins to register features in Backstage for users to opt into. You can use this to split out logic in your code for manual A/B testing, etc.';
|
||||
readonly 'featureFlags.flagItem.title.disable': 'Disable';
|
||||
readonly 'featureFlags.flagItem.title.enable': 'Enable';
|
||||
readonly 'featureFlags.flagItem.subTitle.registeredInApplication': 'Registered in the application';
|
||||
readonly 'featureFlags.flagItem.subTitle.registeredInPlugin': 'Registered in {{pluginId}} plugin';
|
||||
readonly 'languageToggle.select': 'Select language {{language}}';
|
||||
readonly 'languageToggle.title': 'Language';
|
||||
readonly 'languageToggle.description': 'Change the language';
|
||||
@@ -116,6 +126,27 @@ export const userSettingsTranslationRef: TranslationRef<
|
||||
readonly 'themeToggle.names.dark': 'Dark';
|
||||
readonly 'themeToggle.names.light': 'Light';
|
||||
readonly 'themeToggle.selectAuto': 'Select Auto Theme';
|
||||
readonly 'signOutMenu.title': 'Sign Out';
|
||||
readonly 'pinToggle.title': 'Pin Sidebar';
|
||||
readonly 'pinToggle.description': 'Prevent the sidebar from collapsing';
|
||||
readonly 'identityCard.title': 'Backstage Identity';
|
||||
readonly 'identityCard.noIdentityTitle': 'No Backstage Identity';
|
||||
readonly 'identityCard.userEntity': 'User Entity';
|
||||
readonly 'identityCard.ownershipEntities': 'Ownership Entities';
|
||||
readonly 'defaultProviderSettings.description': 'Provides authentication towards {{provider}} APIs and identities';
|
||||
readonly 'emptyProviders.title': 'No Authentication Providers';
|
||||
readonly 'emptyProviders.action.title': 'Open app-config.yaml and make the changes as highlighted below:';
|
||||
readonly 'emptyProviders.action.readMoreButtonTitle': 'Read More';
|
||||
readonly 'emptyProviders.description': 'You can add Authentication Providers to Backstage which allows you to use these providers to authenticate yourself.';
|
||||
readonly 'providerSettingsItem.title.signIn': 'Sign in to {{title}}';
|
||||
readonly 'providerSettingsItem.title.signOut': 'Sign out from {{title}}';
|
||||
readonly 'providerSettingsItem.buttonTitle.signIn': 'Sign in';
|
||||
readonly 'providerSettingsItem.buttonTitle.signOut': 'Sign out';
|
||||
readonly 'authProviders.title': 'Available Providers';
|
||||
readonly 'defaultSettingsPage.tabsTitle.featureFlags': 'Feature Flags';
|
||||
readonly 'defaultSettingsPage.tabsTitle.authProviders': 'Authentication Providers';
|
||||
readonly 'defaultSettingsPage.tabsTitle.general': 'General';
|
||||
readonly 'settingsLayout.title': 'Settings';
|
||||
}
|
||||
>;
|
||||
|
||||
|
||||
@@ -27,18 +27,23 @@ import {
|
||||
atlassianAuthApiRef,
|
||||
oneloginAuthApiRef,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { userSettingsTranslationRef } from '../../translation';
|
||||
import { useTranslationRef } from '@backstage/frontend-plugin-api';
|
||||
|
||||
/** @public */
|
||||
export const DefaultProviderSettings = (props: {
|
||||
configuredProviders: string[];
|
||||
}) => {
|
||||
const { configuredProviders } = props;
|
||||
const { t } = useTranslationRef(userSettingsTranslationRef);
|
||||
return (
|
||||
<>
|
||||
{configuredProviders.includes('google') && (
|
||||
<ProviderSettingsItem
|
||||
title="Google"
|
||||
description="Provides authentication towards Google APIs and identities"
|
||||
description={t('defaultProviderSettings.description', {
|
||||
provider: 'Google',
|
||||
})}
|
||||
apiRef={googleAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
@@ -46,7 +51,9 @@ export const DefaultProviderSettings = (props: {
|
||||
{configuredProviders.includes('microsoft') && (
|
||||
<ProviderSettingsItem
|
||||
title="Microsoft"
|
||||
description="Provides authentication towards Microsoft APIs and identities"
|
||||
description={t('defaultProviderSettings.description', {
|
||||
provider: 'Microsoft',
|
||||
})}
|
||||
apiRef={microsoftAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
@@ -54,7 +61,9 @@ export const DefaultProviderSettings = (props: {
|
||||
{configuredProviders.includes('github') && (
|
||||
<ProviderSettingsItem
|
||||
title="GitHub"
|
||||
description="Provides authentication towards GitHub APIs"
|
||||
description={t('defaultProviderSettings.description', {
|
||||
provider: 'GitHub',
|
||||
})}
|
||||
apiRef={githubAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
@@ -62,7 +71,9 @@ export const DefaultProviderSettings = (props: {
|
||||
{configuredProviders.includes('gitlab') && (
|
||||
<ProviderSettingsItem
|
||||
title="GitLab"
|
||||
description="Provides authentication towards GitLab APIs"
|
||||
description={t('defaultProviderSettings.description', {
|
||||
provider: 'GitLab',
|
||||
})}
|
||||
apiRef={gitlabAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
@@ -70,7 +81,9 @@ export const DefaultProviderSettings = (props: {
|
||||
{configuredProviders.includes('okta') && (
|
||||
<ProviderSettingsItem
|
||||
title="Okta"
|
||||
description="Provides authentication towards Okta APIs"
|
||||
description={t('defaultProviderSettings.description', {
|
||||
provider: 'Okta',
|
||||
})}
|
||||
apiRef={oktaAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
@@ -78,7 +91,9 @@ export const DefaultProviderSettings = (props: {
|
||||
{configuredProviders.includes('bitbucket') && (
|
||||
<ProviderSettingsItem
|
||||
title="Bitbucket"
|
||||
description="Provides authentication towards Bitbucket APIs"
|
||||
description={t('defaultProviderSettings.description', {
|
||||
provider: 'Bitbucket',
|
||||
})}
|
||||
apiRef={bitbucketAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
@@ -86,7 +101,9 @@ export const DefaultProviderSettings = (props: {
|
||||
{configuredProviders.includes('onelogin') && (
|
||||
<ProviderSettingsItem
|
||||
title="OneLogin"
|
||||
description="Provides authentication towards OneLogin APIs"
|
||||
description={t('defaultProviderSettings.description', {
|
||||
provider: 'OneLogin',
|
||||
})}
|
||||
apiRef={oneloginAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
@@ -94,7 +111,9 @@ export const DefaultProviderSettings = (props: {
|
||||
{configuredProviders.includes('atlassian') && (
|
||||
<ProviderSettingsItem
|
||||
title="Atlassian"
|
||||
description="Provides authentication towards Atlassian APIs"
|
||||
description={t('defaultProviderSettings.description', {
|
||||
provider: 'Atlassian',
|
||||
})}
|
||||
apiRef={atlassianAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
@@ -102,7 +121,9 @@ export const DefaultProviderSettings = (props: {
|
||||
{configuredProviders.includes('bitbucketServer') && (
|
||||
<ProviderSettingsItem
|
||||
title="Bitbucket Server"
|
||||
description="Provides authentication towards Bitbucket Server APIs"
|
||||
description={t('defaultProviderSettings.description', {
|
||||
provider: 'Bitbucket Server',
|
||||
})}
|
||||
apiRef={bitbucketServerAuthApiRef}
|
||||
icon={Star}
|
||||
/>
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { CodeSnippet, EmptyState } from '@backstage/core-components';
|
||||
import { useTranslationRef } from '@backstage/frontend-plugin-api';
|
||||
import { userSettingsTranslationRef } from '../../translation';
|
||||
|
||||
const EXAMPLE = `auth:
|
||||
providers:
|
||||
@@ -26,32 +28,34 @@ const EXAMPLE = `auth:
|
||||
clientSecret: \${AUTH_GOOGLE_CLIENT_SECRET}
|
||||
`;
|
||||
|
||||
export const EmptyProviders = () => (
|
||||
<EmptyState
|
||||
missing="content"
|
||||
title="No Authentication Providers"
|
||||
description="You can add Authentication Providers to Backstage which allows you to use these providers to authenticate yourself."
|
||||
action={
|
||||
<>
|
||||
<Typography variant="body1">
|
||||
Open <code>app-config.yaml</code> and make the changes as highlighted
|
||||
below:
|
||||
</Typography>
|
||||
<CodeSnippet
|
||||
text={EXAMPLE}
|
||||
language="yaml"
|
||||
showLineNumbers
|
||||
highlightedNumbers={[3, 4, 5, 6, 7, 8]}
|
||||
customStyle={{ background: 'inherit', fontSize: '115%' }}
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
href="https://backstage.io/docs/auth/add-auth-provider"
|
||||
>
|
||||
Read More
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
export const EmptyProviders = () => {
|
||||
const { t } = useTranslationRef(userSettingsTranslationRef);
|
||||
return (
|
||||
<EmptyState
|
||||
missing="content"
|
||||
title={t('emptyProviders.title')}
|
||||
description={t('emptyProviders.description')}
|
||||
action={
|
||||
<>
|
||||
<Typography variant="body1">
|
||||
{t('emptyProviders.action.title')}
|
||||
</Typography>
|
||||
<CodeSnippet
|
||||
text={EXAMPLE}
|
||||
language="yaml"
|
||||
showLineNumbers
|
||||
highlightedNumbers={[3, 4, 5, 6, 7, 8]}
|
||||
customStyle={{ background: 'inherit', fontSize: '115%' }}
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
href="https://backstage.io/docs/auth/add-auth-provider"
|
||||
>
|
||||
{t('emptyProviders.action.readMoreButtonTitle')}
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -34,6 +34,8 @@ import {
|
||||
IconComponent,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { ProviderSettingsAvatar } from './ProviderSettingsAvatar';
|
||||
import { useTranslationRef } from '@backstage/frontend-plugin-api';
|
||||
import { userSettingsTranslationRef } from '../../translation';
|
||||
|
||||
const emptyProfile: ProfileInfo = {};
|
||||
|
||||
@@ -50,6 +52,7 @@ export const ProviderSettingsItem = (props: {
|
||||
const errorApi = useApi(errorApiRef);
|
||||
const [signedIn, setSignedIn] = useState(false);
|
||||
const [profile, setProfile] = useState<ProfileInfo>(emptyProfile);
|
||||
const { t } = useTranslationRef(userSettingsTranslationRef);
|
||||
|
||||
useEffect(() => {
|
||||
let didCancel = false;
|
||||
@@ -128,7 +131,11 @@ export const ProviderSettingsItem = (props: {
|
||||
<Tooltip
|
||||
placement="top"
|
||||
arrow
|
||||
title={signedIn ? `Sign out from ${title}` : `Sign in to ${title}`}
|
||||
title={
|
||||
signedIn
|
||||
? t('providerSettingsItem.title.signOut', { title })
|
||||
: t('providerSettingsItem.title.signIn', { title })
|
||||
}
|
||||
>
|
||||
<Button
|
||||
variant="outlined"
|
||||
@@ -138,7 +145,9 @@ export const ProviderSettingsItem = (props: {
|
||||
action.catch(error => errorApi.post(error));
|
||||
}}
|
||||
>
|
||||
{signedIn ? `Sign out` : `Sign in`}
|
||||
{signedIn
|
||||
? t('providerSettingsItem.buttonTitle.signOut')
|
||||
: t('providerSettingsItem.buttonTitle.signIn')}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</ListItemSecondaryAction>
|
||||
|
||||
@@ -19,6 +19,8 @@ import { EmptyProviders } from './EmptyProviders';
|
||||
import { DefaultProviderSettings } from './DefaultProviderSettings';
|
||||
import { configApiRef, useApi } from '@backstage/core-plugin-api';
|
||||
import { InfoCard } from '@backstage/core-components';
|
||||
import { userSettingsTranslationRef } from '../../translation';
|
||||
import { useTranslationRef } from '@backstage/frontend-plugin-api';
|
||||
|
||||
/** @public */
|
||||
export const UserSettingsAuthProviders = (props: {
|
||||
@@ -31,13 +33,14 @@ export const UserSettingsAuthProviders = (props: {
|
||||
const providers = providerSettings ?? (
|
||||
<DefaultProviderSettings configuredProviders={configuredProviders} />
|
||||
);
|
||||
const { t } = useTranslationRef(userSettingsTranslationRef);
|
||||
|
||||
if (!providerSettings && !configuredProviders?.length) {
|
||||
return <EmptyProviders />;
|
||||
}
|
||||
|
||||
return (
|
||||
<InfoCard title="Available Providers">
|
||||
<InfoCard title={t('authProviders.title')}>
|
||||
<List dense>{providers}</List>
|
||||
</InfoCard>
|
||||
);
|
||||
|
||||
@@ -19,6 +19,8 @@ import { UserSettingsAuthProviders } from '../AuthProviders';
|
||||
import { UserSettingsFeatureFlags } from '../FeatureFlags';
|
||||
import { UserSettingsGeneral } from '../General';
|
||||
import { SettingsLayout, SettingsLayoutRouteProps } from '../SettingsLayout';
|
||||
import { useTranslationRef } from '@backstage/frontend-plugin-api';
|
||||
import { userSettingsTranslationRef } from '../../translation';
|
||||
|
||||
/**
|
||||
* @public
|
||||
@@ -28,19 +30,26 @@ export const DefaultSettingsPage = (props: {
|
||||
providerSettings?: JSX.Element;
|
||||
}) => {
|
||||
const { providerSettings, tabs } = props;
|
||||
const { t } = useTranslationRef(userSettingsTranslationRef);
|
||||
|
||||
return (
|
||||
<SettingsLayout>
|
||||
<SettingsLayout.Route path="general" title="General">
|
||||
<SettingsLayout.Route
|
||||
path="general"
|
||||
title={t('defaultSettingsPage.tabsTitle.general')}
|
||||
>
|
||||
<UserSettingsGeneral />
|
||||
</SettingsLayout.Route>
|
||||
<SettingsLayout.Route
|
||||
path="auth-providers"
|
||||
title="Authentication Providers"
|
||||
title={t('defaultSettingsPage.tabsTitle.authProviders')}
|
||||
>
|
||||
<UserSettingsAuthProviders providerSettings={providerSettings} />
|
||||
</SettingsLayout.Route>
|
||||
<SettingsLayout.Route path="feature-flags" title="Feature Flags">
|
||||
<SettingsLayout.Route
|
||||
path="feature-flags"
|
||||
title={t('defaultSettingsPage.tabsTitle.featureFlags')}
|
||||
>
|
||||
<UserSettingsFeatureFlags />
|
||||
</SettingsLayout.Route>
|
||||
{tabs}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { CodeSnippet, EmptyState } from '@backstage/core-components';
|
||||
import { useTranslationRef } from '@backstage/frontend-plugin-api';
|
||||
import { userSettingsTranslationRef } from '../../translation';
|
||||
|
||||
const EXAMPLE = `import { createPlugin } from '@backstage/core-plugin-api';
|
||||
|
||||
@@ -26,31 +28,35 @@ export default createPlugin({
|
||||
});
|
||||
`;
|
||||
|
||||
export const EmptyFlags = () => (
|
||||
<EmptyState
|
||||
missing="content"
|
||||
title="No Feature Flags"
|
||||
description="Feature Flags make it possible for plugins to register features in Backstage for users to opt into. You can use this to split out logic in your code for manual A/B testing, etc."
|
||||
action={
|
||||
<>
|
||||
<Typography variant="body1">
|
||||
An example for how to add a feature flag is highlighted below:
|
||||
</Typography>
|
||||
<CodeSnippet
|
||||
text={EXAMPLE}
|
||||
language="typescript"
|
||||
showLineNumbers
|
||||
highlightedNumbers={[6]}
|
||||
customStyle={{ background: 'inherit', fontSize: '115%' }}
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
href="https://backstage.io/docs/api/utility-apis"
|
||||
>
|
||||
Read More
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
export const EmptyFlags = () => {
|
||||
const { t } = useTranslationRef(userSettingsTranslationRef);
|
||||
|
||||
return (
|
||||
<EmptyState
|
||||
missing="content"
|
||||
title={t('featureFlags.emptyFlags.title')}
|
||||
description={t('featureFlags.emptyFlags.description')}
|
||||
action={
|
||||
<>
|
||||
<Typography variant="body1">
|
||||
{t('featureFlags.emptyFlags.action.title')}
|
||||
</Typography>
|
||||
<CodeSnippet
|
||||
text={EXAMPLE}
|
||||
language="typescript"
|
||||
showLineNumbers
|
||||
highlightedNumbers={[6]}
|
||||
customStyle={{ background: 'inherit', fontSize: '115%' }}
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
href="https://backstage.io/docs/api/utility-apis"
|
||||
>
|
||||
{t('featureFlags.emptyFlags.action.readMoreButtonTitle')}
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -20,6 +20,9 @@ import ListItemIcon from '@material-ui/core/ListItemIcon';
|
||||
import Switch from '@material-ui/core/Switch';
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
import { FeatureFlag } from '@backstage/core-plugin-api';
|
||||
import { useTranslationRef } from '@backstage/frontend-plugin-api';
|
||||
import { userSettingsTranslationRef } from '../../translation';
|
||||
import { TranslationFunction } from '@backstage/core-plugin-api/alpha';
|
||||
|
||||
type Props = {
|
||||
flag: FeatureFlag;
|
||||
@@ -27,22 +30,39 @@ type Props = {
|
||||
toggleHandler: Function;
|
||||
};
|
||||
|
||||
const getSecondaryText = (flag: FeatureFlag) => {
|
||||
const getSecondaryText = (
|
||||
flag: FeatureFlag,
|
||||
t: TranslationFunction<typeof userSettingsTranslationRef.T>,
|
||||
) => {
|
||||
if (flag.description) {
|
||||
return flag.description;
|
||||
}
|
||||
return flag.pluginId
|
||||
? `Registered in ${flag.pluginId} plugin`
|
||||
: 'Registered in the application';
|
||||
? t('featureFlags.flagItem.subTitle.registeredInPlugin', {
|
||||
pluginId: flag.pluginId,
|
||||
})
|
||||
: t('featureFlags.flagItem.subTitle.registeredInApplication');
|
||||
};
|
||||
|
||||
export const FlagItem = ({ flag, enabled, toggleHandler }: Props) => (
|
||||
<ListItem divider button onClick={() => toggleHandler(flag.name)}>
|
||||
<ListItemIcon>
|
||||
<Tooltip placement="top" arrow title={enabled ? 'Disable' : 'Enable'}>
|
||||
<Switch color="primary" checked={enabled} name={flag.name} />
|
||||
</Tooltip>
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={flag.name} secondary={getSecondaryText(flag)} />
|
||||
</ListItem>
|
||||
);
|
||||
export const FlagItem = ({ flag, enabled, toggleHandler }: Props) => {
|
||||
const { t } = useTranslationRef(userSettingsTranslationRef);
|
||||
|
||||
return (
|
||||
<ListItem divider button onClick={() => toggleHandler(flag.name)}>
|
||||
<ListItemIcon>
|
||||
<Tooltip
|
||||
placement="top"
|
||||
arrow
|
||||
title={
|
||||
enabled
|
||||
? t('featureFlags.flagItem.title.disable')
|
||||
: t('featureFlags.flagItem.title.enable')
|
||||
}
|
||||
>
|
||||
<Switch color="primary" checked={enabled} name={flag.name} />
|
||||
</Tooltip>
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={flag.name} secondary={getSecondaryText(flag, t)} />
|
||||
</ListItem>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -31,6 +31,8 @@ import {
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { InfoCard } from '@backstage/core-components';
|
||||
import ClearIcon from '@material-ui/icons/Clear';
|
||||
import { useTranslationRef } from '@backstage/frontend-plugin-api';
|
||||
import { userSettingsTranslationRef } from '../../translation';
|
||||
|
||||
export const sortFlags = (
|
||||
flags: FeatureFlag[],
|
||||
@@ -59,6 +61,7 @@ export const UserSettingsFeatureFlags = () => {
|
||||
|
||||
const [state, setState] = useState<Record<string, boolean>>(initialFlagState);
|
||||
const [filterInput, setFilterInput] = useState<string>('');
|
||||
const { t } = useTranslationRef(userSettingsTranslationRef);
|
||||
|
||||
const toggleFlag = useCallback(
|
||||
(flagName: string) => {
|
||||
@@ -96,9 +99,9 @@ export const UserSettingsFeatureFlags = () => {
|
||||
const Header = () => (
|
||||
<Grid container style={{ justifyContent: 'space-between' }}>
|
||||
<Grid item xs={6} md={8}>
|
||||
<Typography variant="h5">Feature Flags</Typography>
|
||||
<Typography variant="h5">{t('featureFlags.title')}</Typography>
|
||||
<Typography variant="subtitle1">
|
||||
Please refresh the page when toggling feature flags
|
||||
{t('featureFlags.description')}
|
||||
</Typography>
|
||||
</Grid>
|
||||
{featureFlags.length >= 10 && (
|
||||
|
||||
@@ -19,25 +19,28 @@ import { EntityRefLinks } from '@backstage/plugin-catalog-react';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { useUserProfile } from '../useUserProfileInfo';
|
||||
import { useTranslationRef } from '@backstage/frontend-plugin-api';
|
||||
import { userSettingsTranslationRef } from '../../translation';
|
||||
|
||||
const Contents = () => {
|
||||
const { backstageIdentity } = useUserProfile();
|
||||
const { t } = useTranslationRef(userSettingsTranslationRef);
|
||||
|
||||
if (!backstageIdentity) {
|
||||
return <Typography>No Backstage Identity</Typography>;
|
||||
return <Typography>{t('identityCard.noIdentityTitle')}</Typography>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid container spacing={1}>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="subtitle1" gutterBottom>
|
||||
User Entity:{' '}
|
||||
{t('identityCard.userEntity')}:{' '}
|
||||
<EntityRefLinks entityRefs={[backstageIdentity.userEntityRef]} />
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="subtitle1">
|
||||
Ownership Entities:{' '}
|
||||
{t('identityCard.ownershipEntities')}:{' '}
|
||||
<EntityRefLinks entityRefs={backstageIdentity.ownershipEntityRefs} />
|
||||
</Typography>
|
||||
</Grid>
|
||||
@@ -46,8 +49,12 @@ const Contents = () => {
|
||||
};
|
||||
|
||||
/** @public */
|
||||
export const UserSettingsIdentityCard = () => (
|
||||
<InfoCard title="Backstage Identity">
|
||||
<Contents />
|
||||
</InfoCard>
|
||||
);
|
||||
export const UserSettingsIdentityCard = () => {
|
||||
const { t } = useTranslationRef(userSettingsTranslationRef);
|
||||
|
||||
return (
|
||||
<InfoCard title={t('identityCard.title')}>
|
||||
<Contents />
|
||||
</InfoCard>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -26,6 +26,8 @@ import {
|
||||
errorApiRef,
|
||||
useApi,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { useTranslationRef } from '@backstage/frontend-plugin-api';
|
||||
import { userSettingsTranslationRef } from '../../translation';
|
||||
|
||||
/** @public */
|
||||
export const UserSettingsMenu = () => {
|
||||
@@ -33,6 +35,7 @@ export const UserSettingsMenu = () => {
|
||||
const identityApi = useApi(identityApiRef);
|
||||
const [open, setOpen] = useState(false);
|
||||
const [anchorEl, setAnchorEl] = useState<undefined | HTMLElement>(undefined);
|
||||
const { t } = useTranslationRef(userSettingsTranslationRef);
|
||||
|
||||
const handleOpen = (event: MouseEvent<HTMLButtonElement>) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
@@ -63,7 +66,7 @@ export const UserSettingsMenu = () => {
|
||||
<ListItemIcon>
|
||||
<SignOutIcon />
|
||||
</ListItemIcon>
|
||||
Sign Out
|
||||
{t('signOutMenu.title')}
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
</>
|
||||
|
||||
@@ -20,16 +20,19 @@ import ListItemText from '@material-ui/core/ListItemText';
|
||||
import Switch from '@material-ui/core/Switch';
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
import { useSidebarPinState } from '@backstage/core-components';
|
||||
import { useTranslationRef } from '@backstage/frontend-plugin-api';
|
||||
import { userSettingsTranslationRef } from '../../translation';
|
||||
|
||||
/** @public */
|
||||
export const UserSettingsPinToggle = () => {
|
||||
const { isPinned, toggleSidebarPinState } = useSidebarPinState();
|
||||
const { t } = useTranslationRef(userSettingsTranslationRef);
|
||||
|
||||
return (
|
||||
<ListItem>
|
||||
<ListItemText
|
||||
primary="Pin Sidebar"
|
||||
secondary="Prevent the sidebar from collapsing"
|
||||
primary={t('pinToggle.title')}
|
||||
secondary={t('pinToggle.description')}
|
||||
/>
|
||||
<ListItemSecondaryAction>
|
||||
<Tooltip
|
||||
|
||||
@@ -26,6 +26,8 @@ import {
|
||||
attachComponentData,
|
||||
useElementFilter,
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { useTranslationRef } from '@backstage/frontend-plugin-api';
|
||||
import { userSettingsTranslationRef } from '../../translation';
|
||||
|
||||
/** @public */
|
||||
export type SettingsLayoutRouteProps = {
|
||||
@@ -57,6 +59,7 @@ export type SettingsLayoutProps = {
|
||||
export const SettingsLayout = (props: SettingsLayoutProps) => {
|
||||
const { title, children } = props;
|
||||
const { isMobile } = useSidebarPinState();
|
||||
const { t } = useTranslationRef(userSettingsTranslationRef);
|
||||
|
||||
const routes = useElementFilter(children, elements =>
|
||||
elements
|
||||
@@ -71,7 +74,7 @@ export const SettingsLayout = (props: SettingsLayoutProps) => {
|
||||
|
||||
return (
|
||||
<Page themeId="home">
|
||||
{!isMobile && <Header title={title ?? 'Settings'} />}
|
||||
{!isMobile && <Header title={title ?? t('settingsLayout.title')} />}
|
||||
<RoutedTabs routes={routes} />
|
||||
</Page>
|
||||
);
|
||||
|
||||
@@ -36,5 +36,80 @@ export const userSettingsTranslationRef = createTranslationRef({
|
||||
auto: 'Auto',
|
||||
},
|
||||
},
|
||||
signOutMenu: {
|
||||
title: 'Sign Out',
|
||||
},
|
||||
pinToggle: {
|
||||
title: 'Pin Sidebar',
|
||||
description: 'Prevent the sidebar from collapsing',
|
||||
},
|
||||
identityCard: {
|
||||
title: 'Backstage Identity',
|
||||
noIdentityTitle: 'No Backstage Identity',
|
||||
userEntity: 'User Entity',
|
||||
ownershipEntities: 'Ownership Entities',
|
||||
},
|
||||
defaultProviderSettings: {
|
||||
description:
|
||||
'Provides authentication towards {{provider}} APIs and identities',
|
||||
},
|
||||
emptyProviders: {
|
||||
title: 'No Authentication Providers',
|
||||
description:
|
||||
'You can add Authentication Providers to Backstage which allows you to use these providers to authenticate yourself.',
|
||||
action: {
|
||||
title:
|
||||
'Open app-config.yaml and make the changes as highlighted below:',
|
||||
readMoreButtonTitle: 'Read More',
|
||||
},
|
||||
},
|
||||
providerSettingsItem: {
|
||||
title: {
|
||||
signIn: 'Sign in to {{title}}',
|
||||
signOut: 'Sign out from {{title}}',
|
||||
},
|
||||
buttonTitle: {
|
||||
signIn: 'Sign in',
|
||||
signOut: 'Sign out',
|
||||
},
|
||||
},
|
||||
authProviders: {
|
||||
title: 'Available Providers',
|
||||
},
|
||||
defaultSettingsPage: {
|
||||
tabsTitle: {
|
||||
general: 'General',
|
||||
authProviders: 'Authentication Providers',
|
||||
featureFlags: 'Feature Flags',
|
||||
},
|
||||
},
|
||||
featureFlags: {
|
||||
title: 'Feature Flags',
|
||||
description: 'Please refresh the page when toggling feature flags',
|
||||
emptyFlags: {
|
||||
title: 'No Feature Flags',
|
||||
description:
|
||||
'Feature Flags make it possible for plugins to register features in Backstage for users to opt into. You can use this to split out logic in your code for manual A/B testing, etc.',
|
||||
action: {
|
||||
title:
|
||||
'An example for how to add a feature flag is highlighted below:',
|
||||
readMoreButtonTitle: 'Read More',
|
||||
},
|
||||
},
|
||||
flagItem: {
|
||||
title: {
|
||||
disable: 'Disable',
|
||||
enable: 'Enable',
|
||||
},
|
||||
subTitle: {
|
||||
registeredInApplication: 'Registered in the application',
|
||||
registeredInPlugin: 'Registered in {{pluginId}} plugin',
|
||||
},
|
||||
},
|
||||
},
|
||||
general: {},
|
||||
settingsLayout: {
|
||||
title: 'Settings',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user