mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-23 00:22:19 +01: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:
parent
6eb3922741
commit
c99470ec4e
@ -18,18 +18,19 @@ import { CopyApiTokenButton } from 'component/admin/apiToken/CopyApiTokenButton/
|
||||
import { RemoveApiTokenButton } from 'component/admin/apiToken/RemoveApiTokenButton/RemoveApiTokenButton';
|
||||
import { DateCell } from 'component/common/Table/cells/DateCell/DateCell';
|
||||
import { sortTypes } from 'utils/sortTypes';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import theme from 'themes/theme';
|
||||
import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig';
|
||||
import { ProjectsList } from 'component/admin/apiToken/ProjectsList/ProjectsList';
|
||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||
import { HighlightCell } from 'component/common/Table/cells/HighlightCell/HighlightCell';
|
||||
import { Search } from 'component/common/Search/Search';
|
||||
import useHiddenColumns from 'hooks/useHiddenColumns';
|
||||
|
||||
export const ApiTokenTable = () => {
|
||||
const { tokens, loading } = useApiTokens();
|
||||
const hiddenColumns = useHiddenColumns();
|
||||
const initialState = useMemo(() => ({ sortBy: [{ id: 'createdAt' }] }), []);
|
||||
const { uiConfig } = useUiConfig();
|
||||
|
||||
const {
|
||||
getTableProps,
|
||||
@ -52,9 +53,16 @@ export const ApiTokenTable = () => {
|
||||
useSortBy
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setHiddenColumns(hiddenColumns);
|
||||
}, [setHiddenColumns, hiddenColumns]);
|
||||
useHiddenColumns(
|
||||
setHiddenColumns,
|
||||
['Icon', 'createdAt'],
|
||||
useMediaQuery(theme.breakpoints.down('md'))
|
||||
);
|
||||
useHiddenColumns(
|
||||
setHiddenColumns,
|
||||
['projects', 'environment'],
|
||||
!uiConfig.flags.E
|
||||
);
|
||||
|
||||
return (
|
||||
<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 = [
|
||||
{
|
||||
id: 'Icon',
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { useEffect, useMemo, useState, VFC } from 'react';
|
||||
import {
|
||||
Button,
|
||||
IconButton,
|
||||
styled,
|
||||
Tooltip,
|
||||
useMediaQuery,
|
||||
useTheme,
|
||||
} 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 { TablePlaceholder, VirtualizedTable } from 'component/common/Table';
|
||||
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 { GroupUserRoleCell } from 'component/admin/groups/GroupUserRoleCell/GroupUserRoleCell';
|
||||
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 { MainHeader } from 'component/common/MainHeader/MainHeader';
|
||||
import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
|
||||
import { RemoveGroup } from 'component/admin/groups/RemoveGroup/RemoveGroup';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { ActionCell } from 'component/common/Table/cells/ActionCell/ActionCell';
|
||||
import { AddGroupUser } from './AddGroupUser/AddGroupUser';
|
||||
import { EditGroupUser } from './EditGroupUser/EditGroupUser';
|
||||
import { RemoveGroupUser } from './RemoveGroupUser/RemoveGroupUser';
|
||||
import { UserAvatar } from 'component/common/UserAvatar/UserAvatar';
|
||||
import ResponsiveButton from 'component/common/ResponsiveButton/ResponsiveButton';
|
||||
import {
|
||||
UG_EDIT_BTN_ID,
|
||||
UG_DELETE_BTN_ID,
|
||||
@ -140,30 +139,36 @@ export const Group: VFC = () => {
|
||||
Cell: ({ row: { original: rowUser } }: any) => (
|
||||
<ActionCell>
|
||||
<Tooltip title="Edit user" arrow describeChild>
|
||||
<IconButton
|
||||
data-testid={`${UG_EDIT_USER_BTN_ID}-${rowUser.id}`}
|
||||
onClick={() => {
|
||||
setSelectedUser(rowUser);
|
||||
setEditUserOpen(true);
|
||||
}}
|
||||
>
|
||||
<Edit />
|
||||
</IconButton>
|
||||
<span>
|
||||
<IconButton
|
||||
data-testid={`${UG_EDIT_USER_BTN_ID}-${rowUser.id}`}
|
||||
disabled={group?.users.length === 1}
|
||||
onClick={() => {
|
||||
setSelectedUser(rowUser);
|
||||
setEditUserOpen(true);
|
||||
}}
|
||||
>
|
||||
<Edit />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
title="Remove user from group"
|
||||
arrow
|
||||
describeChild
|
||||
>
|
||||
<IconButton
|
||||
data-testid={`${UG_REMOVE_USER_BTN_ID}-${rowUser.id}`}
|
||||
onClick={() => {
|
||||
setSelectedUser(rowUser);
|
||||
setRemoveUserOpen(true);
|
||||
}}
|
||||
>
|
||||
<Delete />
|
||||
</IconButton>
|
||||
<span>
|
||||
<IconButton
|
||||
data-testid={`${UG_REMOVE_USER_BTN_ID}-${rowUser.id}`}
|
||||
disabled={group?.users.length === 1}
|
||||
onClick={() => {
|
||||
setSelectedUser(rowUser);
|
||||
setRemoveUserOpen(true);
|
||||
}}
|
||||
>
|
||||
<Delete />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</ActionCell>
|
||||
),
|
||||
@ -171,7 +176,7 @@ export const Group: VFC = () => {
|
||||
disableSortBy: true,
|
||||
},
|
||||
],
|
||||
[setSelectedUser, setRemoveUserOpen]
|
||||
[setSelectedUser, setRemoveUserOpen, group?.users.length]
|
||||
);
|
||||
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
@ -306,16 +311,17 @@ export const Group: VFC = () => {
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
<ResponsiveButton
|
||||
data-testid={UG_ADD_USER_BTN_ID}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
setAddUserOpen(true);
|
||||
}}
|
||||
maxWidth="700px"
|
||||
Icon={Add}
|
||||
permission={ADMIN}
|
||||
>
|
||||
Add user
|
||||
</Button>
|
||||
</ResponsiveButton>
|
||||
</>
|
||||
}
|
||||
>
|
||||
@ -376,13 +382,13 @@ export const Group: VFC = () => {
|
||||
<EditGroupUser
|
||||
open={editUserOpen}
|
||||
setOpen={setEditUserOpen}
|
||||
user={selectedUser!}
|
||||
user={selectedUser}
|
||||
group={group!}
|
||||
/>
|
||||
<RemoveGroupUser
|
||||
open={removeUserOpen}
|
||||
setOpen={setRemoveUserOpen}
|
||||
user={selectedUser!}
|
||||
user={selectedUser}
|
||||
group={group!}
|
||||
/>
|
||||
</PageContent>
|
||||
|
@ -1,5 +1,5 @@
|
||||
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 { IGroupUser } from 'interfaces/group';
|
||||
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 { sortTypes } from 'utils/sortTypes';
|
||||
import { UserAvatar } from 'component/common/UserAvatar/UserAvatar';
|
||||
import theme from 'themes/theme';
|
||||
import useHiddenColumns from 'hooks/useHiddenColumns';
|
||||
|
||||
interface IGroupFormUsersTableProps {
|
||||
users: IGroupUser[];
|
||||
@ -106,7 +108,7 @@ export const GroupFormUsersTable: VFC<IGroupFormUsersTableProps> = ({
|
||||
[setUsers]
|
||||
);
|
||||
|
||||
const { headerGroups, rows, prepareRow } = useTable(
|
||||
const { headerGroups, rows, prepareRow, setHiddenColumns } = useTable(
|
||||
{
|
||||
columns: columns as any[],
|
||||
data: users as any[],
|
||||
@ -119,6 +121,12 @@ export const GroupFormUsersTable: VFC<IGroupFormUsersTableProps> = ({
|
||||
useFlexLayout
|
||||
);
|
||||
|
||||
useHiddenColumns(
|
||||
setHiddenColumns,
|
||||
['imageUrl', 'name'],
|
||||
useMediaQuery(theme.breakpoints.down('md'))
|
||||
);
|
||||
|
||||
return (
|
||||
<ConditionallyRender
|
||||
condition={rows.length > 0}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useEffect, useMemo, useState, VFC } from 'react';
|
||||
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 { PageContent } from 'component/common/PageContent/PageContent';
|
||||
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 { GroupCard } from './GroupCard/GroupCard';
|
||||
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';
|
||||
|
||||
type PageQueryType = Partial<Record<'search', string>>;
|
||||
@ -33,6 +36,7 @@ const groupsSearch = (group: IGroup, searchValue: string) => {
|
||||
};
|
||||
|
||||
export const GroupsList: VFC = () => {
|
||||
const navigate = useNavigate();
|
||||
const { groups = [], loading } = useGroups();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const [searchValue, setSearchValue] = useState(
|
||||
@ -81,15 +85,17 @@ export const GroupsList: VFC = () => {
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
to="/admin/groups/create-group"
|
||||
component={Link}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
<ResponsiveButton
|
||||
onClick={() =>
|
||||
navigate('/admin/groups/create-group')
|
||||
}
|
||||
maxWidth="700px"
|
||||
Icon={Add}
|
||||
permission={ADMIN}
|
||||
data-testid={NAVIGATE_TO_CREATE_GROUP}
|
||||
>
|
||||
New group
|
||||
</Button>
|
||||
</ResponsiveButton>
|
||||
</>
|
||||
}
|
||||
>
|
||||
|
@ -13,7 +13,7 @@ const StyledMainHeader = styled(Paper)(({ theme }) => ({
|
||||
|
||||
const StyledTitleHeader = styled('div')(({ theme }) => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'space-between',
|
||||
}));
|
||||
|
||||
|
@ -47,8 +47,8 @@ const StyledAutocompleteWrapper = styled('div')(({ theme }) => ({
|
||||
},
|
||||
}));
|
||||
|
||||
const StyledButtonContainer = styled('div')(() => ({
|
||||
marginTop: 'auto',
|
||||
const StyledButtonContainer = styled('div')(({ theme }) => ({
|
||||
marginTop: theme.spacing(6),
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
}));
|
||||
|
@ -9,7 +9,7 @@ const StyledDescription = styled('div')(({ theme }) => ({
|
||||
padding: theme.spacing(3),
|
||||
backgroundColor: theme.palette.neutral.light,
|
||||
color: theme.palette.text.secondary,
|
||||
fontSize: theme.fontSizes.smallerBody,
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
borderRadius: theme.shape.borderRadiusMedium,
|
||||
}));
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { useEffect, useMemo, useState, VFC } from 'react';
|
||||
import { SortingRule, useFlexLayout, useSortBy, useTable } from 'react-table';
|
||||
import { VirtualizedTable, TablePlaceholder } from 'component/common/Table';
|
||||
import { Button, useMediaQuery, useTheme } from '@mui/material';
|
||||
import { Delete, Edit } from '@mui/icons-material';
|
||||
import { styled, useMediaQuery, useTheme } from '@mui/material';
|
||||
import { Add, Delete, Edit } from '@mui/icons-material';
|
||||
import { sortTypes } from 'utils/sortTypes';
|
||||
import useProjectAccess, {
|
||||
ENTITY_TYPE,
|
||||
@ -38,9 +38,11 @@ import { IUser } from 'interfaces/user';
|
||||
import { IGroup } from 'interfaces/group';
|
||||
import { LinkCell } from 'component/common/Table/cells/LinkCell/LinkCell';
|
||||
import { UserAvatar } from 'component/common/UserAvatar/UserAvatar';
|
||||
import ResponsiveButton from 'component/common/ResponsiveButton/ResponsiveButton';
|
||||
import { ProjectAccessCreate } from 'component/project/ProjectAccess/ProjectAccessCreate/ProjectAccessCreate';
|
||||
import { ProjectAccessEditUser } from 'component/project/ProjectAccess/ProjectAccessEditUser/ProjectAccessEditUser';
|
||||
import { ProjectAccessEditGroup } from 'component/project/ProjectAccess/ProjectAccessEditGroup/ProjectAccessEditGroup';
|
||||
import useHiddenColumns from 'hooks/useHiddenColumns';
|
||||
|
||||
export type PageQueryType = Partial<
|
||||
Record<'sort' | 'order' | 'search', string>
|
||||
@ -53,6 +55,20 @@ const { value: storedParams, setValue: setStoredParams } = createLocalStorage(
|
||||
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 = () => {
|
||||
const projectId = useRequiredPathParam('projectId');
|
||||
|
||||
@ -77,11 +93,15 @@ export const ProjectAccessTable: VFC = () => {
|
||||
Header: 'Avatar',
|
||||
accessor: 'imageUrl',
|
||||
Cell: ({ row: { original: row } }: any) => (
|
||||
<TextCell>
|
||||
<UserAvatar user={row.entity}>
|
||||
<StyledUserAvatars>
|
||||
<ConditionallyRender
|
||||
condition={row.type === ENTITY_TYPE.GROUP}
|
||||
show={<StyledEmptyAvatar />}
|
||||
/>
|
||||
<StyledGroupAvatar user={row.entity}>
|
||||
{row.entity.users?.length}
|
||||
</UserAvatar>
|
||||
</TextCell>
|
||||
</StyledGroupAvatar>
|
||||
</StyledUserAvatars>
|
||||
),
|
||||
maxWidth: 85,
|
||||
disableSortBy: true,
|
||||
@ -124,6 +144,7 @@ export const ProjectAccessTable: VFC = () => {
|
||||
searchable: true,
|
||||
},
|
||||
{
|
||||
id: 'role',
|
||||
Header: 'Role',
|
||||
accessor: (row: IProjectAccess) =>
|
||||
access?.roles.find(({ id }) => id === row.entity.roleId)
|
||||
@ -145,6 +166,7 @@ export const ProjectAccessTable: VFC = () => {
|
||||
maxWidth: 150,
|
||||
},
|
||||
{
|
||||
id: 'lastLogin',
|
||||
Header: 'Last login',
|
||||
accessor: (row: IProjectAccess) => {
|
||||
if (row.type === ENTITY_TYPE.USER) {
|
||||
@ -240,6 +262,7 @@ export const ProjectAccessTable: VFC = () => {
|
||||
headerGroups,
|
||||
rows,
|
||||
prepareRow,
|
||||
setHiddenColumns,
|
||||
state: { sortBy },
|
||||
} = useTable(
|
||||
{
|
||||
@ -258,6 +281,12 @@ export const ProjectAccessTable: VFC = () => {
|
||||
useFlexLayout
|
||||
);
|
||||
|
||||
useHiddenColumns(
|
||||
setHiddenColumns,
|
||||
['imageUrl', 'username', 'role', 'added', 'lastLogin'],
|
||||
isSmallScreen
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const tableState: PageQueryType = {};
|
||||
tableState.sort = sortBy[0].id;
|
||||
@ -332,14 +361,15 @@ export const ProjectAccessTable: VFC = () => {
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Button
|
||||
component={Link}
|
||||
to={`create`}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
<ResponsiveButton
|
||||
onClick={() => navigate('create')}
|
||||
maxWidth="700px"
|
||||
Icon={Add}
|
||||
permission={UPDATE_PROJECT}
|
||||
projectId={projectId}
|
||||
>
|
||||
Assign {entityType}
|
||||
</Button>
|
||||
</ResponsiveButton>
|
||||
</>
|
||||
}
|
||||
>
|
||||
|
@ -20,17 +20,22 @@ import { IGroup, IGroupUser } from 'interfaces/group';
|
||||
import { VFC, useState } from 'react';
|
||||
import { SortingRule, useFlexLayout, useSortBy, useTable } from 'react-table';
|
||||
import { sortTypes } from 'utils/sortTypes';
|
||||
import useHiddenColumns from 'hooks/useHiddenColumns';
|
||||
|
||||
const StyledPageContent = styled(PageContent)(({ theme }) => ({
|
||||
height: '100vh',
|
||||
overflow: 'auto',
|
||||
padding: theme.spacing(7.5, 6),
|
||||
[theme.breakpoints.down('md')]: {
|
||||
padding: theme.spacing(4, 2),
|
||||
},
|
||||
'& .header': {
|
||||
padding: theme.spacing(0, 0, 2, 0),
|
||||
},
|
||||
'& .body': {
|
||||
padding: theme.spacing(3, 0, 0, 0),
|
||||
},
|
||||
borderRadius: `${theme.spacing(1.5, 0, 0, 1.5)} !important`,
|
||||
}));
|
||||
|
||||
const StyledTitle = styled('div')(({ theme }) => ({
|
||||
@ -38,7 +43,7 @@ const StyledTitle = styled('div')(({ theme }) => ({
|
||||
flexDirection: 'column',
|
||||
'& > span': {
|
||||
color: theme.palette.text.secondary,
|
||||
fontSize: theme.fontSizes.smallBody,
|
||||
fontSize: theme.fontSizes.bodySize,
|
||||
},
|
||||
}));
|
||||
|
||||
@ -80,6 +85,7 @@ const columns = [
|
||||
filterName: 'type',
|
||||
},
|
||||
{
|
||||
id: 'joined',
|
||||
Header: 'Joined',
|
||||
accessor: 'joinedAt',
|
||||
Cell: DateCell,
|
||||
@ -87,6 +93,7 @@ const columns = [
|
||||
maxWidth: 150,
|
||||
},
|
||||
{
|
||||
id: 'lastLogin',
|
||||
Header: 'Last login',
|
||||
accessor: (row: IGroupUser) => row.seenAt || '',
|
||||
Cell: ({ row: { original: user } }: any) => (
|
||||
@ -135,7 +142,7 @@ export const ProjectGroupView: VFC<IProjectGroupViewProps> = ({
|
||||
group?.users ?? []
|
||||
);
|
||||
|
||||
const { headerGroups, rows, prepareRow } = useTable(
|
||||
const { headerGroups, rows, prepareRow, setHiddenColumns } = useTable(
|
||||
{
|
||||
columns: columns as any[],
|
||||
data,
|
||||
@ -149,6 +156,12 @@ export const ProjectGroupView: VFC<IProjectGroupViewProps> = ({
|
||||
useFlexLayout
|
||||
);
|
||||
|
||||
useHiddenColumns(
|
||||
setHiddenColumns,
|
||||
['imageUrl', 'name', 'joined', 'lastLogin'],
|
||||
useMediaQuery(theme.breakpoints.down('md'))
|
||||
);
|
||||
|
||||
return (
|
||||
<SidebarModal
|
||||
open={open}
|
||||
|
15
frontend/src/hooks/useHiddenColumns.ts
Normal file
15
frontend/src/hooks/useHiddenColumns.ts
Normal 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;
|
Loading…
Reference in New Issue
Block a user