1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-06-23 01:16:27 +02:00

Feat/groups refinements (#1197)

* Improvements

* Double icon for group

* Hide columns

* Refinements

* Refinements

* Reduce padding

* Add projectId

* Fixes

* Make useHiddenColumns component
This commit is contained in:
sjaanus 2022-08-05 16:10:53 +03:00 committed by GitHub
parent 6eb3922741
commit c99470ec4e
10 changed files with 147 additions and 82 deletions

View File

@ -18,18 +18,19 @@ import { CopyApiTokenButton } from 'component/admin/apiToken/CopyApiTokenButton/
import { RemoveApiTokenButton } from 'component/admin/apiToken/RemoveApiTokenButton/RemoveApiTokenButton'; import { RemoveApiTokenButton } from 'component/admin/apiToken/RemoveApiTokenButton/RemoveApiTokenButton';
import { DateCell } from 'component/common/Table/cells/DateCell/DateCell'; import { DateCell } from 'component/common/Table/cells/DateCell/DateCell';
import { sortTypes } from 'utils/sortTypes'; import { sortTypes } from 'utils/sortTypes';
import { useEffect, useMemo } from 'react'; import { useMemo } from 'react';
import theme from 'themes/theme'; import theme from 'themes/theme';
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
import { ProjectsList } from 'component/admin/apiToken/ProjectsList/ProjectsList'; import { ProjectsList } from 'component/admin/apiToken/ProjectsList/ProjectsList';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender'; import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { HighlightCell } from 'component/common/Table/cells/HighlightCell/HighlightCell'; import { HighlightCell } from 'component/common/Table/cells/HighlightCell/HighlightCell';
import { Search } from 'component/common/Search/Search'; import { Search } from 'component/common/Search/Search';
import useHiddenColumns from 'hooks/useHiddenColumns';
export const ApiTokenTable = () => { export const ApiTokenTable = () => {
const { tokens, loading } = useApiTokens(); const { tokens, loading } = useApiTokens();
const hiddenColumns = useHiddenColumns();
const initialState = useMemo(() => ({ sortBy: [{ id: 'createdAt' }] }), []); const initialState = useMemo(() => ({ sortBy: [{ id: 'createdAt' }] }), []);
const { uiConfig } = useUiConfig();
const { const {
getTableProps, getTableProps,
@ -52,9 +53,16 @@ export const ApiTokenTable = () => {
useSortBy useSortBy
); );
useEffect(() => { useHiddenColumns(
setHiddenColumns(hiddenColumns); setHiddenColumns,
}, [setHiddenColumns, hiddenColumns]); ['Icon', 'createdAt'],
useMediaQuery(theme.breakpoints.down('md'))
);
useHiddenColumns(
setHiddenColumns,
['projects', 'environment'],
!uiConfig.flags.E
);
return ( return (
<PageContent <PageContent
@ -124,27 +132,6 @@ export const ApiTokenTable = () => {
); );
}; };
const useHiddenColumns = (): string[] => {
const { uiConfig } = useUiConfig();
const isMediumScreen = useMediaQuery(theme.breakpoints.down('md'));
return useMemo(() => {
const hidden: string[] = [];
if (!uiConfig.flags.E) {
hidden.push('projects');
hidden.push('environment');
}
if (isMediumScreen) {
hidden.push('Icon');
hidden.push('createdAt');
}
return hidden;
}, [uiConfig, isMediumScreen]);
};
const COLUMNS = [ const COLUMNS = [
{ {
id: 'Icon', id: 'Icon',

View File

@ -1,13 +1,12 @@
import { useEffect, useMemo, useState, VFC } from 'react'; import { useEffect, useMemo, useState, VFC } from 'react';
import { import {
Button,
IconButton, IconButton,
styled, styled,
Tooltip, Tooltip,
useMediaQuery, useMediaQuery,
useTheme, useTheme,
} from '@mui/material'; } from '@mui/material';
import { useSearchParams } from 'react-router-dom'; import { useSearchParams, Link } from 'react-router-dom';
import { SortingRule, useFlexLayout, useSortBy, useTable } from 'react-table'; import { SortingRule, useFlexLayout, useSortBy, useTable } from 'react-table';
import { TablePlaceholder, VirtualizedTable } from 'component/common/Table'; import { TablePlaceholder, VirtualizedTable } from 'component/common/Table';
import { useGroup } from 'hooks/api/getters/useGroup/useGroup'; import { useGroup } from 'hooks/api/getters/useGroup/useGroup';
@ -26,17 +25,17 @@ import { HighlightCell } from 'component/common/Table/cells/HighlightCell/Highli
import { TimeAgoCell } from 'component/common/Table/cells/TimeAgoCell/TimeAgoCell'; import { TimeAgoCell } from 'component/common/Table/cells/TimeAgoCell/TimeAgoCell';
import { GroupUserRoleCell } from 'component/admin/groups/GroupUserRoleCell/GroupUserRoleCell'; import { GroupUserRoleCell } from 'component/admin/groups/GroupUserRoleCell/GroupUserRoleCell';
import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton';
import { Delete, Edit } from '@mui/icons-material'; import { Add, Delete, Edit } from '@mui/icons-material';
import { ADMIN } from 'component/providers/AccessProvider/permissions'; import { ADMIN } from 'component/providers/AccessProvider/permissions';
import { MainHeader } from 'component/common/MainHeader/MainHeader'; import { MainHeader } from 'component/common/MainHeader/MainHeader';
import { useRequiredPathParam } from 'hooks/useRequiredPathParam'; import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { RemoveGroup } from 'component/admin/groups/RemoveGroup/RemoveGroup'; import { RemoveGroup } from 'component/admin/groups/RemoveGroup/RemoveGroup';
import { Link } from 'react-router-dom';
import { ActionCell } from 'component/common/Table/cells/ActionCell/ActionCell'; import { ActionCell } from 'component/common/Table/cells/ActionCell/ActionCell';
import { AddGroupUser } from './AddGroupUser/AddGroupUser'; import { AddGroupUser } from './AddGroupUser/AddGroupUser';
import { EditGroupUser } from './EditGroupUser/EditGroupUser'; import { EditGroupUser } from './EditGroupUser/EditGroupUser';
import { RemoveGroupUser } from './RemoveGroupUser/RemoveGroupUser'; import { RemoveGroupUser } from './RemoveGroupUser/RemoveGroupUser';
import { UserAvatar } from 'component/common/UserAvatar/UserAvatar'; import { UserAvatar } from 'component/common/UserAvatar/UserAvatar';
import ResponsiveButton from 'component/common/ResponsiveButton/ResponsiveButton';
import { import {
UG_EDIT_BTN_ID, UG_EDIT_BTN_ID,
UG_DELETE_BTN_ID, UG_DELETE_BTN_ID,
@ -140,8 +139,10 @@ export const Group: VFC = () => {
Cell: ({ row: { original: rowUser } }: any) => ( Cell: ({ row: { original: rowUser } }: any) => (
<ActionCell> <ActionCell>
<Tooltip title="Edit user" arrow describeChild> <Tooltip title="Edit user" arrow describeChild>
<span>
<IconButton <IconButton
data-testid={`${UG_EDIT_USER_BTN_ID}-${rowUser.id}`} data-testid={`${UG_EDIT_USER_BTN_ID}-${rowUser.id}`}
disabled={group?.users.length === 1}
onClick={() => { onClick={() => {
setSelectedUser(rowUser); setSelectedUser(rowUser);
setEditUserOpen(true); setEditUserOpen(true);
@ -149,14 +150,17 @@ export const Group: VFC = () => {
> >
<Edit /> <Edit />
</IconButton> </IconButton>
</span>
</Tooltip> </Tooltip>
<Tooltip <Tooltip
title="Remove user from group" title="Remove user from group"
arrow arrow
describeChild describeChild
> >
<span>
<IconButton <IconButton
data-testid={`${UG_REMOVE_USER_BTN_ID}-${rowUser.id}`} data-testid={`${UG_REMOVE_USER_BTN_ID}-${rowUser.id}`}
disabled={group?.users.length === 1}
onClick={() => { onClick={() => {
setSelectedUser(rowUser); setSelectedUser(rowUser);
setRemoveUserOpen(true); setRemoveUserOpen(true);
@ -164,6 +168,7 @@ export const Group: VFC = () => {
> >
<Delete /> <Delete />
</IconButton> </IconButton>
</span>
</Tooltip> </Tooltip>
</ActionCell> </ActionCell>
), ),
@ -171,7 +176,7 @@ export const Group: VFC = () => {
disableSortBy: true, disableSortBy: true,
}, },
], ],
[setSelectedUser, setRemoveUserOpen] [setSelectedUser, setRemoveUserOpen, group?.users.length]
); );
const [searchParams, setSearchParams] = useSearchParams(); const [searchParams, setSearchParams] = useSearchParams();
@ -306,16 +311,17 @@ export const Group: VFC = () => {
</> </>
} }
/> />
<Button <ResponsiveButton
data-testid={UG_ADD_USER_BTN_ID} data-testid={UG_ADD_USER_BTN_ID}
variant="contained"
color="primary"
onClick={() => { onClick={() => {
setAddUserOpen(true); setAddUserOpen(true);
}} }}
maxWidth="700px"
Icon={Add}
permission={ADMIN}
> >
Add user Add user
</Button> </ResponsiveButton>
</> </>
} }
> >
@ -376,13 +382,13 @@ export const Group: VFC = () => {
<EditGroupUser <EditGroupUser
open={editUserOpen} open={editUserOpen}
setOpen={setEditUserOpen} setOpen={setEditUserOpen}
user={selectedUser!} user={selectedUser}
group={group!} group={group!}
/> />
<RemoveGroupUser <RemoveGroupUser
open={removeUserOpen} open={removeUserOpen}
setOpen={setRemoveUserOpen} setOpen={setRemoveUserOpen}
user={selectedUser!} user={selectedUser}
group={group!} group={group!}
/> />
</PageContent> </PageContent>

View File

@ -1,5 +1,5 @@
import { useMemo, VFC } from 'react'; import { useMemo, VFC } from 'react';
import { IconButton, Tooltip } from '@mui/material'; import { IconButton, Tooltip, useMediaQuery } from '@mui/material';
import { TextCell } from 'component/common/Table/cells/TextCell/TextCell'; import { TextCell } from 'component/common/Table/cells/TextCell/TextCell';
import { IGroupUser } from 'interfaces/group'; import { IGroupUser } from 'interfaces/group';
import { HighlightCell } from 'component/common/Table/cells/HighlightCell/HighlightCell'; import { HighlightCell } from 'component/common/Table/cells/HighlightCell/HighlightCell';
@ -11,6 +11,8 @@ import { VirtualizedTable } from 'component/common/Table';
import { useFlexLayout, useSortBy, useTable } from 'react-table'; import { useFlexLayout, useSortBy, useTable } from 'react-table';
import { sortTypes } from 'utils/sortTypes'; import { sortTypes } from 'utils/sortTypes';
import { UserAvatar } from 'component/common/UserAvatar/UserAvatar'; import { UserAvatar } from 'component/common/UserAvatar/UserAvatar';
import theme from 'themes/theme';
import useHiddenColumns from 'hooks/useHiddenColumns';
interface IGroupFormUsersTableProps { interface IGroupFormUsersTableProps {
users: IGroupUser[]; users: IGroupUser[];
@ -106,7 +108,7 @@ export const GroupFormUsersTable: VFC<IGroupFormUsersTableProps> = ({
[setUsers] [setUsers]
); );
const { headerGroups, rows, prepareRow } = useTable( const { headerGroups, rows, prepareRow, setHiddenColumns } = useTable(
{ {
columns: columns as any[], columns: columns as any[],
data: users as any[], data: users as any[],
@ -119,6 +121,12 @@ export const GroupFormUsersTable: VFC<IGroupFormUsersTableProps> = ({
useFlexLayout useFlexLayout
); );
useHiddenColumns(
setHiddenColumns,
['imageUrl', 'name'],
useMediaQuery(theme.breakpoints.down('md'))
);
return ( return (
<ConditionallyRender <ConditionallyRender
condition={rows.length > 0} condition={rows.length > 0}

View File

@ -1,6 +1,6 @@
import { useEffect, useMemo, useState, VFC } from 'react'; import { useEffect, useMemo, useState, VFC } from 'react';
import { useGroups } from 'hooks/api/getters/useGroups/useGroups'; import { useGroups } from 'hooks/api/getters/useGroups/useGroups';
import { Link, useSearchParams } from 'react-router-dom'; import { Link, useNavigate, useSearchParams } from 'react-router-dom';
import { IGroup } from 'interfaces/group'; import { IGroup } from 'interfaces/group';
import { PageContent } from 'component/common/PageContent/PageContent'; import { PageContent } from 'component/common/PageContent/PageContent';
import { PageHeader } from 'component/common/PageHeader/PageHeader'; import { PageHeader } from 'component/common/PageHeader/PageHeader';
@ -12,6 +12,9 @@ import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightC
import { TablePlaceholder } from 'component/common/Table'; import { TablePlaceholder } from 'component/common/Table';
import { GroupCard } from './GroupCard/GroupCard'; import { GroupCard } from './GroupCard/GroupCard';
import { GroupEmpty } from './GroupEmpty/GroupEmpty'; import { GroupEmpty } from './GroupEmpty/GroupEmpty';
import ResponsiveButton from 'component/common/ResponsiveButton/ResponsiveButton';
import { ADMIN } from 'component/providers/AccessProvider/permissions';
import { Add } from '@mui/icons-material';
import { NAVIGATE_TO_CREATE_GROUP } from 'utils/testIds'; import { NAVIGATE_TO_CREATE_GROUP } from 'utils/testIds';
type PageQueryType = Partial<Record<'search', string>>; type PageQueryType = Partial<Record<'search', string>>;
@ -33,6 +36,7 @@ const groupsSearch = (group: IGroup, searchValue: string) => {
}; };
export const GroupsList: VFC = () => { export const GroupsList: VFC = () => {
const navigate = useNavigate();
const { groups = [], loading } = useGroups(); const { groups = [], loading } = useGroups();
const [searchParams, setSearchParams] = useSearchParams(); const [searchParams, setSearchParams] = useSearchParams();
const [searchValue, setSearchValue] = useState( const [searchValue, setSearchValue] = useState(
@ -81,15 +85,17 @@ export const GroupsList: VFC = () => {
</> </>
} }
/> />
<Button <ResponsiveButton
to="/admin/groups/create-group" onClick={() =>
component={Link} navigate('/admin/groups/create-group')
variant="contained" }
color="primary" maxWidth="700px"
Icon={Add}
permission={ADMIN}
data-testid={NAVIGATE_TO_CREATE_GROUP} data-testid={NAVIGATE_TO_CREATE_GROUP}
> >
New group New group
</Button> </ResponsiveButton>
</> </>
} }
> >

View File

@ -13,7 +13,7 @@ const StyledMainHeader = styled(Paper)(({ theme }) => ({
const StyledTitleHeader = styled('div')(({ theme }) => ({ const StyledTitleHeader = styled('div')(({ theme }) => ({
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'flex-start',
justifyContent: 'space-between', justifyContent: 'space-between',
})); }));

View File

@ -47,8 +47,8 @@ const StyledAutocompleteWrapper = styled('div')(({ theme }) => ({
}, },
})); }));
const StyledButtonContainer = styled('div')(() => ({ const StyledButtonContainer = styled('div')(({ theme }) => ({
marginTop: 'auto', marginTop: theme.spacing(6),
display: 'flex', display: 'flex',
justifyContent: 'flex-end', justifyContent: 'flex-end',
})); }));

View File

@ -9,7 +9,7 @@ const StyledDescription = styled('div')(({ theme }) => ({
padding: theme.spacing(3), padding: theme.spacing(3),
backgroundColor: theme.palette.neutral.light, backgroundColor: theme.palette.neutral.light,
color: theme.palette.text.secondary, color: theme.palette.text.secondary,
fontSize: theme.fontSizes.smallerBody, fontSize: theme.fontSizes.smallBody,
borderRadius: theme.shape.borderRadiusMedium, borderRadius: theme.shape.borderRadiusMedium,
})); }));

View File

@ -1,8 +1,8 @@
import { useEffect, useMemo, useState, VFC } from 'react'; import { useEffect, useMemo, useState, VFC } from 'react';
import { SortingRule, useFlexLayout, useSortBy, useTable } from 'react-table'; import { SortingRule, useFlexLayout, useSortBy, useTable } from 'react-table';
import { VirtualizedTable, TablePlaceholder } from 'component/common/Table'; import { VirtualizedTable, TablePlaceholder } from 'component/common/Table';
import { Button, useMediaQuery, useTheme } from '@mui/material'; import { styled, useMediaQuery, useTheme } from '@mui/material';
import { Delete, Edit } from '@mui/icons-material'; import { Add, Delete, Edit } from '@mui/icons-material';
import { sortTypes } from 'utils/sortTypes'; import { sortTypes } from 'utils/sortTypes';
import useProjectAccess, { import useProjectAccess, {
ENTITY_TYPE, ENTITY_TYPE,
@ -38,9 +38,11 @@ import { IUser } from 'interfaces/user';
import { IGroup } from 'interfaces/group'; import { IGroup } from 'interfaces/group';
import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell'; import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell';
import { UserAvatar } from 'component/common/UserAvatar/UserAvatar'; import { UserAvatar } from 'component/common/UserAvatar/UserAvatar';
import ResponsiveButton from 'component/common/ResponsiveButton/ResponsiveButton';
import { ProjectAccessCreate } from 'component/project/ProjectAccess/ProjectAccessCreate/ProjectAccessCreate'; import { ProjectAccessCreate } from 'component/project/ProjectAccess/ProjectAccessCreate/ProjectAccessCreate';
import { ProjectAccessEditUser } from 'component/project/ProjectAccess/ProjectAccessEditUser/ProjectAccessEditUser'; import { ProjectAccessEditUser } from 'component/project/ProjectAccess/ProjectAccessEditUser/ProjectAccessEditUser';
import { ProjectAccessEditGroup } from 'component/project/ProjectAccess/ProjectAccessEditGroup/ProjectAccessEditGroup'; import { ProjectAccessEditGroup } from 'component/project/ProjectAccess/ProjectAccessEditGroup/ProjectAccessEditGroup';
import useHiddenColumns from 'hooks/useHiddenColumns';
export type PageQueryType = Partial< export type PageQueryType = Partial<
Record<'sort' | 'order' | 'search', string> Record<'sort' | 'order' | 'search', string>
@ -53,6 +55,20 @@ const { value: storedParams, setValue: setStoredParams } = createLocalStorage(
defaultSort defaultSort
); );
const StyledUserAvatars = styled('div')(({ theme }) => ({
display: 'inline-flex',
alignItems: 'center',
flexWrap: 'wrap',
marginLeft: theme.spacing(1),
}));
const StyledEmptyAvatar = styled(UserAvatar)(({ theme }) => ({
marginRight: theme.spacing(-3.5),
}));
const StyledGroupAvatar = styled(UserAvatar)(({ theme }) => ({
outline: `${theme.spacing(0.25)} solid ${theme.palette.background.paper}`,
}));
export const ProjectAccessTable: VFC = () => { export const ProjectAccessTable: VFC = () => {
const projectId = useRequiredPathParam('projectId'); const projectId = useRequiredPathParam('projectId');
@ -77,11 +93,15 @@ export const ProjectAccessTable: VFC = () => {
Header: 'Avatar', Header: 'Avatar',
accessor: 'imageUrl', accessor: 'imageUrl',
Cell: ({ row: { original: row } }: any) => ( Cell: ({ row: { original: row } }: any) => (
<TextCell> <StyledUserAvatars>
<UserAvatar user={row.entity}> <ConditionallyRender
condition={row.type === ENTITY_TYPE.GROUP}
show={<StyledEmptyAvatar />}
/>
<StyledGroupAvatar user={row.entity}>
{row.entity.users?.length} {row.entity.users?.length}
</UserAvatar> </StyledGroupAvatar>
</TextCell> </StyledUserAvatars>
), ),
maxWidth: 85, maxWidth: 85,
disableSortBy: true, disableSortBy: true,
@ -124,6 +144,7 @@ export const ProjectAccessTable: VFC = () => {
searchable: true, searchable: true,
}, },
{ {
id: 'role',
Header: 'Role', Header: 'Role',
accessor: (row: IProjectAccess) => accessor: (row: IProjectAccess) =>
access?.roles.find(({ id }) => id === row.entity.roleId) access?.roles.find(({ id }) => id === row.entity.roleId)
@ -145,6 +166,7 @@ export const ProjectAccessTable: VFC = () => {
maxWidth: 150, maxWidth: 150,
}, },
{ {
id: 'lastLogin',
Header: 'Last login', Header: 'Last login',
accessor: (row: IProjectAccess) => { accessor: (row: IProjectAccess) => {
if (row.type === ENTITY_TYPE.USER) { if (row.type === ENTITY_TYPE.USER) {
@ -240,6 +262,7 @@ export const ProjectAccessTable: VFC = () => {
headerGroups, headerGroups,
rows, rows,
prepareRow, prepareRow,
setHiddenColumns,
state: { sortBy }, state: { sortBy },
} = useTable( } = useTable(
{ {
@ -258,6 +281,12 @@ export const ProjectAccessTable: VFC = () => {
useFlexLayout useFlexLayout
); );
useHiddenColumns(
setHiddenColumns,
['imageUrl', 'username', 'role', 'added', 'lastLogin'],
isSmallScreen
);
useEffect(() => { useEffect(() => {
const tableState: PageQueryType = {}; const tableState: PageQueryType = {};
tableState.sort = sortBy[0].id; tableState.sort = sortBy[0].id;
@ -332,14 +361,15 @@ export const ProjectAccessTable: VFC = () => {
</> </>
} }
/> />
<Button <ResponsiveButton
component={Link} onClick={() => navigate('create')}
to={`create`} maxWidth="700px"
variant="contained" Icon={Add}
color="primary" permission={UPDATE_PROJECT}
projectId={projectId}
> >
Assign {entityType} Assign {entityType}
</Button> </ResponsiveButton>
</> </>
} }
> >

View File

@ -20,17 +20,22 @@ import { IGroup, IGroupUser } from 'interfaces/group';
import { VFC, useState } from 'react'; import { VFC, useState } from 'react';
import { SortingRule, useFlexLayout, useSortBy, useTable } from 'react-table'; import { SortingRule, useFlexLayout, useSortBy, useTable } from 'react-table';
import { sortTypes } from 'utils/sortTypes'; import { sortTypes } from 'utils/sortTypes';
import useHiddenColumns from 'hooks/useHiddenColumns';
const StyledPageContent = styled(PageContent)(({ theme }) => ({ const StyledPageContent = styled(PageContent)(({ theme }) => ({
height: '100vh', height: '100vh',
overflow: 'auto', overflow: 'auto',
padding: theme.spacing(7.5, 6), padding: theme.spacing(7.5, 6),
[theme.breakpoints.down('md')]: {
padding: theme.spacing(4, 2),
},
'& .header': { '& .header': {
padding: theme.spacing(0, 0, 2, 0), padding: theme.spacing(0, 0, 2, 0),
}, },
'& .body': { '& .body': {
padding: theme.spacing(3, 0, 0, 0), padding: theme.spacing(3, 0, 0, 0),
}, },
borderRadius: `${theme.spacing(1.5, 0, 0, 1.5)} !important`,
})); }));
const StyledTitle = styled('div')(({ theme }) => ({ const StyledTitle = styled('div')(({ theme }) => ({
@ -38,7 +43,7 @@ const StyledTitle = styled('div')(({ theme }) => ({
flexDirection: 'column', flexDirection: 'column',
'& > span': { '& > span': {
color: theme.palette.text.secondary, color: theme.palette.text.secondary,
fontSize: theme.fontSizes.smallBody, fontSize: theme.fontSizes.bodySize,
}, },
})); }));
@ -80,6 +85,7 @@ const columns = [
filterName: 'type', filterName: 'type',
}, },
{ {
id: 'joined',
Header: 'Joined', Header: 'Joined',
accessor: 'joinedAt', accessor: 'joinedAt',
Cell: DateCell, Cell: DateCell,
@ -87,6 +93,7 @@ const columns = [
maxWidth: 150, maxWidth: 150,
}, },
{ {
id: 'lastLogin',
Header: 'Last login', Header: 'Last login',
accessor: (row: IGroupUser) => row.seenAt || '', accessor: (row: IGroupUser) => row.seenAt || '',
Cell: ({ row: { original: user } }: any) => ( Cell: ({ row: { original: user } }: any) => (
@ -135,7 +142,7 @@ export const ProjectGroupView: VFC<IProjectGroupViewProps> = ({
group?.users ?? [] group?.users ?? []
); );
const { headerGroups, rows, prepareRow } = useTable( const { headerGroups, rows, prepareRow, setHiddenColumns } = useTable(
{ {
columns: columns as any[], columns: columns as any[],
data, data,
@ -149,6 +156,12 @@ export const ProjectGroupView: VFC<IProjectGroupViewProps> = ({
useFlexLayout useFlexLayout
); );
useHiddenColumns(
setHiddenColumns,
['imageUrl', 'name', 'joined', 'lastLogin'],
useMediaQuery(theme.breakpoints.down('md'))
);
return ( return (
<SidebarModal <SidebarModal
open={open} open={open}

View File

@ -0,0 +1,15 @@
import { useEffect } from 'react';
import { IdType } from 'react-table';
const useHiddenColumns = (
setHiddenColumns: <D>(param: Array<IdType<D>>) => void,
hiddenColumns: string[],
condition: boolean
) => {
useEffect(() => {
const hidden = condition ? hiddenColumns : [];
setHiddenColumns(hidden);
}, [setHiddenColumns, condition]);
};
export default useHiddenColumns;