([]);
- const styles = useStyles2(getStyles);
useEffect(() => {
async function fetchOptions() {
@@ -148,7 +146,18 @@ export const OrgUsersTable = ({
{
id: 'info',
header: '',
- cell: InfoCell,
+ cell: ({ row: { original } }: Cell) => {
+ const basicRoleDisabled = getBasicRoleDisabled(original);
+ return (
+ basicRoleDisabled && (
+
+
+
+
+
+ )
+ );
+ },
},
{
id: 'authLabels',
@@ -186,18 +195,18 @@ export const OrgUsersTable = ({
);
return (
-
-
+
+
String(user.userId)}
fetchData={fetchData}
/>
-
+
-
-
+
+
{Boolean(userToRemove) && (
)}
-
+
);
};
-
-const InfoCell = ({ row: { original } }: Cell) => {
- const styles = useStyles2(getStyles);
- const basicRoleDisabled = getBasicRoleDisabled(original);
- return (
- basicRoleDisabled && (
-
-
-
-
-
- )
- );
-};
-
-const getStyles = (theme: GrafanaTheme2) => ({
- row: css({
- display: 'flex',
- alignItems: 'center',
- }),
- icon: css({
- marginLeft: theme.spacing(1),
- }),
- // Enable RolePicker overflow
- wrapper: css({
- display: 'flex',
- flexDirection: 'column',
- overflowX: 'auto',
- overflowY: 'hidden',
- minHeight: '100vh',
- width: '100%',
- '& > div': {
- overflowX: 'unset',
- marginBottom: theme.spacing(2),
- },
- }),
-});
diff --git a/public/app/features/admin/Users/TableWrapper.tsx b/public/app/features/admin/Users/TableWrapper.tsx
new file mode 100644
index 00000000000..ea3fd28809d
--- /dev/null
+++ b/public/app/features/admin/Users/TableWrapper.tsx
@@ -0,0 +1,30 @@
+import { css } from '@emotion/css';
+import React, { PropsWithChildren } from 'react';
+
+import { GrafanaTheme2 } from '@grafana/data';
+import { useStyles2 } from '@grafana/ui';
+
+/**
+ * A wrapper component for interactive tables using RolePicker to enable overflow.
+ * Should be removed when the RolePicker component uses portals to render its menu
+ */
+export const TableWrapper = ({ children }: PropsWithChildren) => {
+ const styles = useStyles2(getStyles);
+ return {children}
;
+};
+
+const getStyles = (theme: GrafanaTheme2) => ({
+ // Enable RolePicker overflow
+ wrapper: css({
+ display: 'flex',
+ flexDirection: 'column',
+ overflowX: 'auto',
+ overflowY: 'hidden',
+ minHeight: '100vh',
+ width: '100%',
+ '& > div': {
+ overflowX: 'unset',
+ marginBottom: theme.spacing(2),
+ },
+ }),
+});
diff --git a/public/app/features/admin/Users/UsersTable.tsx b/public/app/features/admin/Users/UsersTable.tsx
index 1f9ec1b7e4c..209625698cd 100644
--- a/public/app/features/admin/Users/UsersTable.tsx
+++ b/public/app/features/admin/Users/UsersTable.tsx
@@ -1,21 +1,18 @@
-import { css } from '@emotion/css';
import React, { useMemo } from 'react';
-import { GrafanaTheme2 } from '@grafana/data';
import {
InteractiveTable,
CellProps,
Tooltip,
Icon,
- useStyles2,
Tag,
Pagination,
Column,
- VerticalGroup,
- HorizontalGroup,
FetchDataFunc,
+ Text,
Avatar,
} from '@grafana/ui';
+import { Flex, Stack } from '@grafana/ui/src/unstable';
import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
import { UserDTO } from 'app/types';
@@ -69,7 +66,18 @@ export const UsersTable = ({
{
id: 'orgs',
header: 'Belongs to',
- cell: OrgUnitsCell,
+ cell: ({ cell: { value, row } }: Cell<'orgs'>) => {
+ return (
+
+
+ {row.original.isAdmin && (
+
+
+
+ )}
+
+ );
+ },
sortType: (a, b) => (a.original.orgs?.length || 0) - (b.original.orgs?.length || 0),
},
...(showLicensedRole
@@ -77,7 +85,18 @@ export const UsersTable = ({
{
id: 'licensedRole',
header: 'Licensed role',
- cell: LicensedRoleCell,
+ cell: ({ cell: { value } }: Cell<'licensedRole'>) => {
+ return value === 'None' ? (
+
+ Not assigned{' '}
+
+
+
+
+ ) : (
+ value
+ );
+ },
// Needs the assertion here, the types are not inferred correctly due to the conditional assignment
sortType: 'string' as const,
},
@@ -90,7 +109,9 @@ export const UsersTable = ({
content: 'Time since user was seen using Grafana',
iconName: 'question-circle',
},
- cell: LastSeenAtCell,
+ cell: ({ cell: { value } }: Cell<'lastSeenAtAge'>) => {
+ return <>{value && <>{value === '10 years' ? Never : value}>}>;
+ },
sortType: (a, b) => new Date(a.original.lastSeenAt!).getTime() - new Date(b.original.lastSeenAt!).getTime(),
},
{
@@ -122,62 +143,13 @@ export const UsersTable = ({
[showLicensedRole]
);
return (
-
+
String(user.id)} fetchData={fetchData} />
{showPaging && (
-
+
-
+
)}
-
+
);
};
-
-const OrgUnitsCell = ({ cell: { value, row } }: Cell<'orgs'>) => {
- const styles = useStyles2(getStyles);
- return (
-
-
- {row.original.isAdmin && (
-
-
-
- )}
-
- );
-};
-
-const LicensedRoleCell = ({ cell: { value } }: Cell<'licensedRole'>) => {
- const styles = useStyles2(getStyles);
-
- return (
- <>
- {value === 'None' ? (
-
- Not assigned{' '}
-
-
-
-
- ) : (
- value
- )}
- >
- );
-};
-
-const LastSeenAtCell = ({ cell: { value } }: Cell<'lastSeenAtAge'>) => {
- const styles = useStyles2(getStyles);
-
- return <>{value && <>{value === '10 years' ? Never : value}>}>;
-};
-
-const getStyles = (theme: GrafanaTheme2) => {
- return {
- disabled: css({ color: theme.colors.text.disabled }),
- row: css({
- display: 'flex',
- alignItems: 'center',
- }),
- };
-};
diff --git a/public/app/features/teams/TeamList.tsx b/public/app/features/teams/TeamList.tsx
index 04a269e23bb..435ab51fa02 100644
--- a/public/app/features/teams/TeamList.tsx
+++ b/public/app/features/teams/TeamList.tsx
@@ -1,8 +1,6 @@
-import { css } from '@emotion/css';
import React, { useEffect, useMemo, useState } from 'react';
import { connect, ConnectedProps } from 'react-redux';
-import { GrafanaTheme2 } from '@grafana/data';
import {
LinkButton,
FilterInput,
@@ -13,12 +11,10 @@ import {
Icon,
Tooltip,
Column,
- HorizontalGroup,
Pagination,
- VerticalGroup,
- useStyles2,
Avatar,
} from '@grafana/ui';
+import { Stack, Flex } from '@grafana/ui/src/unstable';
import EmptyListCTA from 'app/core/components/EmptyListCTA/EmptyListCTA';
import { Page } from 'app/core/components/Page/Page';
import { fetchRoleOptions } from 'app/core/components/RolePicker/api';
@@ -26,6 +22,7 @@ import { contextSrv } from 'app/core/services/context_srv';
import { AccessControlAction, Role, StoreState, Team } from 'app/types';
import { TeamRolePicker } from '../../core/components/RolePicker/TeamRolePicker';
+import { TableWrapper } from '../admin/Users/TableWrapper';
import { deleteTeam, loadTeams, changePage, changeQuery, changeSort } from './state/actions';
@@ -50,7 +47,6 @@ export const TeamList = ({
changeSort,
}: Props) => {
const [roleOptions, setRoleOptions] = useState([]);
- const styles = useStyles2(getStyles);
useEffect(() => {
loadTeams(true);
@@ -165,24 +161,24 @@ export const TeamList = ({
New Team
-
-
+
+
String(team.id)}
fetchData={changeSort}
/>
-
+
-
-
-
+
+
+
>
)}
@@ -190,24 +186,6 @@ export const TeamList = ({
);
};
-const getStyles = (theme: GrafanaTheme2) => {
- return {
- // Enable RolePicker overflow
- wrapper: css({
- display: 'flex',
- flexDirection: 'column',
- overflowX: 'auto',
- overflowY: 'hidden',
- minHeight: '100vh',
- width: '100%',
- '& > div': {
- overflowX: 'unset',
- marginBottom: theme.spacing(2),
- },
- }),
- };
-};
-
function shouldDisplayRolePicker(): boolean {
return (
contextSrv.licensedAccessControlEnabled() &&