Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add empty state and loading state to Users & User Groups #1707

Merged
merged 1 commit into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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