mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Navigation: Use new page layout in Service accounts item page (#54200)
* use navId, pageNav and update alignments of service account page * Fixing item header when feature is disabled * Fix orgs item page * Minor tweak to subtitle for service account item page Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
parent
552d3fec8d
commit
9f8cb17b01
@ -2,7 +2,7 @@
|
|||||||
import { css, cx } from '@emotion/css';
|
import { css, cx } from '@emotion/css';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { GrafanaTheme2, NavModel, NavModelItem } from '@grafana/data';
|
import { GrafanaTheme2 } from '@grafana/data';
|
||||||
import { config } from '@grafana/runtime';
|
import { config } from '@grafana/runtime';
|
||||||
import { CustomScrollbar, useStyles2 } from '@grafana/ui';
|
import { CustomScrollbar, useStyles2 } from '@grafana/ui';
|
||||||
|
|
||||||
@ -32,7 +32,7 @@ export const OldPage: PageType = ({
|
|||||||
|
|
||||||
usePageTitle(navModel, pageNav);
|
usePageTitle(navModel, pageNav);
|
||||||
|
|
||||||
const pageHeaderNav = getPageHeaderNav(navModel, pageNav);
|
const pageHeaderNav = pageNav ?? navModel?.main;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cx(styles.wrapper, className)}>
|
<div className={cx(styles.wrapper, className)}>
|
||||||
@ -59,14 +59,6 @@ export const OldPage: PageType = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function getPageHeaderNav(navModel?: NavModel, pageNav?: NavModelItem): NavModelItem | undefined {
|
|
||||||
if (pageNav?.children && pageNav.children.length > 0) {
|
|
||||||
return pageNav;
|
|
||||||
}
|
|
||||||
|
|
||||||
return navModel?.main;
|
|
||||||
}
|
|
||||||
|
|
||||||
OldPage.Header = PageHeader;
|
OldPage.Header = PageHeader;
|
||||||
OldPage.Contents = PageContents;
|
OldPage.Contents = PageContents;
|
||||||
OldPage.OldNavOnly = OldNavOnly;
|
OldPage.OldNavOnly = OldNavOnly;
|
||||||
|
@ -68,6 +68,9 @@ export default function AdminEditOrgPage({ match }: Props) {
|
|||||||
|
|
||||||
const pageNav: NavModelItem = {
|
const pageNav: NavModelItem = {
|
||||||
text: orgState?.value?.name ?? '',
|
text: orgState?.value?.name ?? '',
|
||||||
|
icon: 'shield',
|
||||||
|
breadcrumbs: [{ title: 'Orgs', url: 'admin/orgs' }],
|
||||||
|
subTitle: 'Manage settings and user roles for an organization.',
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -105,12 +105,16 @@ export class UserAdminPage extends PureComponent<Props> {
|
|||||||
const isLDAPUser = user && user.isExternal && user.authLabels && user.authLabels.includes('LDAP');
|
const isLDAPUser = user && user.isExternal && user.authLabels && user.authLabels.includes('LDAP');
|
||||||
const canReadSessions = contextSrv.hasPermission(AccessControlAction.UsersAuthTokenList);
|
const canReadSessions = contextSrv.hasPermission(AccessControlAction.UsersAuthTokenList);
|
||||||
const canReadLDAPStatus = contextSrv.hasPermission(AccessControlAction.LDAPStatusRead);
|
const canReadLDAPStatus = contextSrv.hasPermission(AccessControlAction.LDAPStatusRead);
|
||||||
|
|
||||||
const pageNav: NavModelItem = {
|
const pageNav: NavModelItem = {
|
||||||
text: user?.login ?? '',
|
text: user?.login ?? '',
|
||||||
|
icon: 'shield',
|
||||||
|
breadcrumbs: [{ title: 'Users', url: 'admin/users' }],
|
||||||
|
subTitle: 'Manage settings for an individual user.',
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page navId="global-users" pageNav={pageNav} subTitle="Manage settings for an individual user.">
|
<Page navId="global-users" pageNav={pageNav}>
|
||||||
<Page.Contents isLoading={isLoading}>
|
<Page.Contents isLoading={isLoading}>
|
||||||
{user && (
|
{user && (
|
||||||
<>
|
<>
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { css } from '@emotion/css';
|
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { connect, ConnectedProps } from 'react-redux';
|
import { connect, ConnectedProps } from 'react-redux';
|
||||||
|
|
||||||
import { getTimeZone, GrafanaTheme2 } from '@grafana/data';
|
import { getTimeZone, NavModelItem } from '@grafana/data';
|
||||||
import { Button, ConfirmModal, IconButton, useStyles2 } from '@grafana/ui';
|
import { Button, ConfirmModal, HorizontalGroup } from '@grafana/ui';
|
||||||
import { Page } from 'app/core/components/Page/Page';
|
import { Page } from 'app/core/components/Page/Page';
|
||||||
import { contextSrv } from 'app/core/core';
|
import { contextSrv } from 'app/core/core';
|
||||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||||
@ -71,7 +70,7 @@ export const ServiceAccountPageUnconnected = ({
|
|||||||
const [isTokenModalOpen, setIsTokenModalOpen] = useState(false);
|
const [isTokenModalOpen, setIsTokenModalOpen] = useState(false);
|
||||||
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
|
||||||
const [isDisableModalOpen, setIsDisableModalOpen] = useState(false);
|
const [isDisableModalOpen, setIsDisableModalOpen] = useState(false);
|
||||||
const styles = useStyles2(getStyles);
|
|
||||||
const serviceAccountId = parseInt(match.params.id, 10);
|
const serviceAccountId = parseInt(match.params.id, 10);
|
||||||
const tokenActionsDisabled =
|
const tokenActionsDisabled =
|
||||||
!contextSrv.hasPermission(AccessControlAction.ServiceAccountsWrite) || serviceAccount.isDisabled;
|
!contextSrv.hasPermission(AccessControlAction.ServiceAccountsWrite) || serviceAccount.isDisabled;
|
||||||
@ -83,6 +82,13 @@ export const ServiceAccountPageUnconnected = ({
|
|||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const pageNav: NavModelItem = {
|
||||||
|
text: serviceAccount.name,
|
||||||
|
img: serviceAccount.avatarUrl,
|
||||||
|
breadcrumbs: [{ title: 'Service accounts', url: 'org/serviceaccounts' }],
|
||||||
|
subTitle: 'Manage settings for an individual service account.',
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
loadServiceAccount(serviceAccountId);
|
loadServiceAccount(serviceAccountId);
|
||||||
loadServiceAccountTokens(serviceAccountId);
|
loadServiceAccountTokens(serviceAccountId);
|
||||||
@ -130,24 +136,11 @@ export const ServiceAccountPageUnconnected = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page navId="serviceaccounts">
|
<Page navId="serviceaccounts" pageNav={pageNav}>
|
||||||
<Page.Contents isLoading={isLoading}>
|
<Page.Contents isLoading={isLoading}>
|
||||||
{serviceAccount && (
|
<div>
|
||||||
<div className={styles.headerContainer}>
|
{serviceAccount && (
|
||||||
<a href="org/serviceaccounts">
|
<HorizontalGroup spacing="md" height="auto" justify="flex-end">
|
||||||
<IconButton
|
|
||||||
size="xxl"
|
|
||||||
variant="secondary"
|
|
||||||
name="arrow-left"
|
|
||||||
className={styles.returnButton}
|
|
||||||
aria-label="Back to service accounts list"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
<div className={styles.headerAvatar}>
|
|
||||||
<img src={serviceAccount.avatarUrl} alt={`Avatar for user ${serviceAccount.name}`} />
|
|
||||||
</div>
|
|
||||||
<h3>{serviceAccount.name}</h3>
|
|
||||||
<div className={styles.buttonRow}>
|
|
||||||
<Button
|
<Button
|
||||||
type={'button'}
|
type={'button'}
|
||||||
variant="destructive"
|
variant="destructive"
|
||||||
@ -175,10 +168,8 @@ export const ServiceAccountPageUnconnected = ({
|
|||||||
Disable service account
|
Disable service account
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</HorizontalGroup>
|
||||||
</div>
|
)}
|
||||||
)}
|
|
||||||
<div className={styles.pageBody}>
|
|
||||||
{serviceAccount && (
|
{serviceAccount && (
|
||||||
<ServiceAccountProfile
|
<ServiceAccountProfile
|
||||||
serviceAccount={serviceAccount}
|
serviceAccount={serviceAccount}
|
||||||
@ -187,12 +178,12 @@ export const ServiceAccountPageUnconnected = ({
|
|||||||
onChange={onProfileChange}
|
onChange={onProfileChange}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div className={styles.tokensListHeader}>
|
<HorizontalGroup justify="space-between" height="auto">
|
||||||
<h3>Tokens</h3>
|
<h3>Tokens</h3>
|
||||||
<Button onClick={() => setIsTokenModalOpen(true)} disabled={tokenActionsDisabled}>
|
<Button onClick={() => setIsTokenModalOpen(true)} disabled={tokenActionsDisabled}>
|
||||||
Add service account token
|
Add service account token
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</HorizontalGroup>
|
||||||
{tokens && (
|
{tokens && (
|
||||||
<ServiceAccountTokensTable
|
<ServiceAccountTokensTable
|
||||||
tokens={tokens}
|
tokens={tokens}
|
||||||
@ -203,6 +194,7 @@ export const ServiceAccountPageUnconnected = ({
|
|||||||
)}
|
)}
|
||||||
{canReadPermissions && <ServiceAccountPermissions serviceAccount={serviceAccount} />}
|
{canReadPermissions && <ServiceAccountPermissions serviceAccount={serviceAccount} />}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ConfirmModal
|
<ConfirmModal
|
||||||
isOpen={isDeleteModalOpen}
|
isOpen={isDeleteModalOpen}
|
||||||
title="Delete service account"
|
title="Delete service account"
|
||||||
@ -231,44 +223,4 @@ export const ServiceAccountPageUnconnected = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getStyles = (theme: GrafanaTheme2) => {
|
|
||||||
return {
|
|
||||||
headerContainer: css`
|
|
||||||
display: flex;
|
|
||||||
margin-bottom: ${theme.spacing(2)};
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
margin-bottom: ${theme.spacing(0.5)};
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
headerAvatar: css`
|
|
||||||
margin-right: ${theme.spacing(1)};
|
|
||||||
margin-bottom: ${theme.spacing(0.6)};
|
|
||||||
img {
|
|
||||||
width: 25px;
|
|
||||||
height: 25px;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
returnButton: css`
|
|
||||||
margin-right: ${theme.spacing(1)};
|
|
||||||
`,
|
|
||||||
buttonRow: css`
|
|
||||||
> * {
|
|
||||||
margin-right: ${theme.spacing(2)};
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
pageBody: css`
|
|
||||||
padding-left: ${theme.spacing(5.5)};
|
|
||||||
`,
|
|
||||||
tokensListHeader: css`
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
`,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ServiceAccountPage = connector(ServiceAccountPageUnconnected);
|
export const ServiceAccountPage = connector(ServiceAccountPageUnconnected);
|
||||||
|
Loading…
Reference in New Issue
Block a user