Skip to content

Commit

Permalink
feat: add empty state and loading state to Users & User Groups (#1707)
Browse files Browse the repository at this point in the history
  • Loading branch information
radekkaluzik authored Nov 15, 2024
1 parent 6471b3c commit 92ea430
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 79 deletions.
80 changes: 37 additions & 43 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
"@commitlint/cli": "^19.5.0",
"@commitlint/config-conventional": "^19.5.0",
"@redhat-cloud-services/eslint-config-redhat-cloud-services": "^2.0.3",
"@redhat-cloud-services/frontend-components-config": "^6.3.1",
"@redhat-cloud-services/frontend-components-config": "^6.3.3",
"@redhat-cloud-services/tsc-transform-imports": "^1.0.4",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/commit-analyzer": "^13.0.0",
Expand Down
20 changes: 20 additions & 0 deletions src/Messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -2294,6 +2294,26 @@ export default defineMessages({
defaultMessage:
'Select a user group to add <b>{numUsers} {plural}</b> to. These are all the user groups in your account. To manage user groups, go to user groups.',
},
usersEmptyStateTitle: {
id: 'usersEmptyStateTitle',
description: 'Empty state title Users',
defaultMessage: 'No users found',
},
usersEmptyStateSubtitle: {
id: 'usersEmptyStateSubtitle',
description: 'Empty state subtitle Users',
defaultMessage: 'This filter criteria matches no users.{br}Try changing your filter input.',
},
userGroupsEmptyStateTitle: {
id: 'userGroupsEmptyStateTitle',
description: 'Empty state title User groups',
defaultMessage: 'No user group found',
},
userGroupsEmptyStateSubtitle: {
id: 'userGroupsEmptyStateSubtitle',
description: 'Empty state subtitle User groups',
defaultMessage: 'This filter criteria matches no user groups.{br}Try changing your filter input.',
},
assignedRoles: {
id: 'assignedRoles',
description: 'User details assigned roles label',
Expand Down
50 changes: 42 additions & 8 deletions src/smart-components/access-management/UserGroupsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import React, { useEffect, useCallback, useMemo } from 'react';
import React, { useEffect, useCallback, useMemo, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { useDataViewSelection, useDataViewPagination } from '@patternfly/react-data-view/dist/dynamic/Hooks';
import { BulkSelect, BulkSelectValue } from '@patternfly/react-component-groups/dist/dynamic/BulkSelect';
import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView';
import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar';
import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
import { Pagination, Tooltip } from '@patternfly/react-core';
import { ActionsColumn } from '@patternfly/react-table';
import { EmptyState, EmptyStateBody, EmptyStateHeader, EmptyStateIcon, Pagination, Tooltip } from '@patternfly/react-core';
import { ActionsColumn, TableVariant } from '@patternfly/react-table';
import { mappedProps } from '../../helpers/shared/helpers';
import { RBACStore } from '../../redux/store';
import { useSearchParams } from 'react-router-dom';
import { fetchGroups } from '../../redux/actions/group-actions';
import { formatDistanceToNow } from 'date-fns';
import { useIntl } from 'react-intl';
import { FormattedMessage, useIntl } from 'react-intl';
import messages from '../../Messages';
import { Group } from '../../redux/reducers/group-reducer';
import { EventTypes, useDataViewEventsContext } from '@patternfly/react-data-view';
import { DataViewState, EventTypes, useDataViewEventsContext } from '@patternfly/react-data-view';
import { SearchIcon } from '@patternfly/react-icons';
import { SkeletonTable } from '@patternfly/react-component-groups';

const COLUMNS: string[] = ['User group name', 'Description', 'Users', 'Service accounts', 'Roles', 'Workspaces', 'Last modified'];

Expand Down Expand Up @@ -45,6 +47,7 @@ const UserGroupsTable: React.FunctionComponent<UserGroupsTableProps> = ({
focusedGroup,
}) => {
const dispatch = useDispatch();
const [activeState, setActiveState] = useState<DataViewState | undefined>(DataViewState.loading);
const intl = useIntl();
const { trigger } = useDataViewEventsContext();

Expand All @@ -53,9 +56,10 @@ const UserGroupsTable: React.FunctionComponent<UserGroupsTableProps> = ({
{ title: intl.formatMessage(messages['usersAndUserGroupsDeleteUserGroup']), onClick: () => console.log('DELETE USER GROUP') },
];

const { groups, totalCount } = useSelector((state: RBACStore) => ({
const { groups, totalCount, isLoading } = useSelector((state: RBACStore) => ({
groups: state.groupReducer?.groups?.data || [],
totalCount: state.groupReducer?.groups?.meta.count || 0,
isLoading: state.groupReducer?.isLoading,
}));

let pagination;
Expand Down Expand Up @@ -99,6 +103,14 @@ const UserGroupsTable: React.FunctionComponent<UserGroupsTableProps> = ({
});
}, [fetchData, page, perPage]);

useEffect(() => {
if (isLoading) {
setActiveState(DataViewState.loading);
} else {
totalCount === 0 ? setActiveState(DataViewState.empty) : setActiveState(undefined);
}
}, [totalCount, isLoading]);

useEffect(() => {
onChange?.(selected);
}, [selected]);
Expand Down Expand Up @@ -161,8 +173,26 @@ const UserGroupsTable: React.FunctionComponent<UserGroupsTableProps> = ({
/>
);

const empty = (
<EmptyState>
<EmptyStateHeader
titleText={intl.formatMessage(messages.userGroupsEmptyStateTitle)}
headingLevel="h4"
icon={<EmptyStateIcon icon={SearchIcon} />}
/>
<EmptyStateBody>
<FormattedMessage
{...messages['userGroupsEmptyStateSubtitle']}
values={{
br: <br />,
}}
/>
</EmptyStateBody>
</EmptyState>
);

return (
<DataView ouiaId={ouiaId} selection={selection}>
<DataView ouiaId={ouiaId} selection={selection} activeState={activeState}>
<DataViewToolbar
ouiaId={`${ouiaId}-header-toolbar`}
bulkSelect={
Expand All @@ -178,7 +208,11 @@ const UserGroupsTable: React.FunctionComponent<UserGroupsTableProps> = ({
}
pagination={React.cloneElement(paginationComponent, { isCompact: true })}
/>
<DataViewTable variant="compact" aria-label="Users Table" ouiaId={`${ouiaId}-table`} columns={COLUMNS} rows={rows} />
{isLoading ? (
<SkeletonTable rowsCount={10} columns={COLUMNS} variant={TableVariant.compact} />
) : (
<DataViewTable variant="compact" aria-label="Users Table" ouiaId={`${ouiaId}-table`} columns={COLUMNS} rows={rows} states={{ empty }} />
)}
<DataViewToolbar ouiaId={`${ouiaId}-footer-toolbar`} pagination={paginationComponent} />
</DataView>
);
Expand Down
Loading

0 comments on commit 92ea430

Please sign in to comment.