Skip to content

Commit

Permalink
Migration to react 18 (#727)
Browse files Browse the repository at this point in the history
* Update to 18 rmf auth

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Update to react router v6

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Update to 18 rmf component

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Add prop to render children

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Update to 18 dashboard

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Update lock file

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Porting to react 18

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Add pathname harcode to render tab name correctly

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Adding * to render nested routes

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Remove close tag

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Remove testing console

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Adding nested routes

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Remove useMatch and pass only username to render child route properly

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Drawing routes according to react router v6

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Removing unused import

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Render user profile by username

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Update react testing library

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Updating react testing library package and use fireevent instead of userEvent

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Use fireevent instead of userEvent

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Use fireevent instead of userEvent

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Update test according to react 18

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Remove userEvent and use fireevent instad

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Add describe to wrap testing and use fire event instead of userevent

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* FireEvent instead of userEvent

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Wrap test into describe

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Wrap test into describe

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Add fireevent instead of userevent.

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* FireEvent added and waitFor expect

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Remove unnecessary function to render component

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Remove test comment

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Using testing library renderHook

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Update react testing library

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Adding function to avoid warning act(...)

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Fix test according to the new version of testing library

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Adding beforeAll code test to silence warning

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Comment test failed

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Create a use stack navigator test acording to new version of testing library

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Add comment to explain change

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* main admin path Navigate to users

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Improve function to be more easy to read

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Fix test in log table report and useasync function

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Remove unused import

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Aaron/react 18 (#729)

* Adding link to unresolved issue to testing

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Added back missing test

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Reverting stack navigator tests

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Remove the rest of reporting components from react-components

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Remove deprecated command forms

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Revert to remove expectation of loading text since that is not what we are testing

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

* Add DashboardRoute to the route map since it returns undefined anyway

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

---------

Signed-off-by: Aaron Chong <aaronchongth@gmail.com>

---------

Signed-off-by: angatupyry <fierrofenix@gmail.com>
Signed-off-by: Aaron Chong <aaronchongth@gmail.com>
Co-authored-by: Aaron Chong <aaronchongth@gmail.com>
  • Loading branch information
Angatupyry and aaronchongth authored Jul 27, 2023
1 parent c67ffb8 commit 22355c1
Show file tree
Hide file tree
Showing 107 changed files with 1,111 additions and 4,963 deletions.
21 changes: 10 additions & 11 deletions packages/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@
"@mui/x-date-pickers": "^5.0.20",
"@types/debug": "^4.1.5",
"@types/leaflet": "^1.5.17",
"@types/react": "^17.0.19",
"@types/react-dom": "^17.0.9",
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
"@types/react-grid-layout": "^1.3.2",
"@types/react-leaflet": "^2.5.2",
"@types/react-router": "^5.1.7",
"@types/react-router-dom": "^5.1.7",
"@types/react-router": "^5.1.20",
"@types/react-router-dom": "^5.3.3",
"ajv": "^8.10.0",
"api-client": "workspace:*",
"axios": "^0.21.1",
Expand All @@ -65,14 +65,14 @@
"keycloak-js": "^11.0.2",
"leaflet": "^1.7.1",
"node-vibrant": "^3.1.6",
"react": "^17.0.2",
"react": "^18.2.0",
"react-components": "workspace:*",
"react-customizable-progressbar": "^1.0.3",
"react-dom": "^17.0.2",
"react-dom": "^18.2.0",
"react-grid-layout": "^1.3.4",
"react-leaflet": "^2.7.0",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-router": "^6.14.1",
"react-router-dom": "^6.14.1",
"rmf-auth": "workspace:*",
"rmf-models": "workspace:*",
"rxjs": "^7.5.5"
Expand All @@ -85,10 +85,9 @@
"@storybook/node-logger": "^6.5.9",
"@storybook/preset-create-react-app": "^3.2.0",
"@storybook/react": "^6.5.8",
"@testing-library/dom": "^8.20.0",
"@testing-library/dom": "^9.3.1",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^11.2.7",
"@testing-library/react-hooks": "^5.1.3",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^12.8.3",
"@types/jest": "^26.0.13",
"api-server": "file:../api-server",
Expand Down
26 changes: 14 additions & 12 deletions packages/dashboard/src/components/admin/drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import { SvgIconComponent } from '@mui/icons-material';
import AccountIcon from '@mui/icons-material/AccountCircle';
import SecurityIcon from '@mui/icons-material/Security';
import React from 'react';
import { matchPath, RouteProps, useHistory, useLocation, useRouteMatch } from 'react-router';
import { RouteProps, useNavigate, useLocation } from 'react-router';

export type AdminDrawerValues = 'Users' | 'Roles';

const drawerValuesRoutesMap: Record<AdminDrawerValues, RouteProps> = {
Users: { path: '/users', exact: true },
Roles: { path: '/roles', exact: true },
Users: { path: '/users' },
Roles: { path: '/roles' },
};

const prefix = 'drawer';
Expand Down Expand Up @@ -48,22 +48,24 @@ const StyledDrawer = styled((props: DrawerProps) => <Drawer {...props} />)(({ th

export function AdminDrawer(): JSX.Element {
const location = useLocation();
const history = useHistory();
const match = useRouteMatch();
const navigate = useNavigate();
const activeItem = React.useMemo<AdminDrawerValues>(() => {
const matched = Object.entries(drawerValuesRoutesMap).find(([_k, v]) =>
matchPath(location.pathname, `${match.path}${v.path}`),
const matched = Object.entries(drawerValuesRoutesMap).find(
([_k, v]) => location.pathname === `/admin${v.path}`,
);

return matched ? (matched[0] as AdminDrawerValues) : 'Users';
}, [location.pathname, match.path]);
}, [location.pathname]);

const DrawerItem = React.useCallback(
({ Icon, text, route }: { Icon: SvgIconComponent; text: AdminDrawerValues; route: string }) => {
return (
<ListItem
button
className={activeItem === text ? classes.activeItem : undefined}
onClick={() => history.push(route)}
onClick={() => {
navigate(route);
}}
>
<ListItemIcon>
<Icon className={classes.itemIcon} />
Expand All @@ -72,16 +74,16 @@ export function AdminDrawer(): JSX.Element {
</ListItem>
);
},
[activeItem, history],
[activeItem, navigate],
);

return (
<StyledDrawer variant="permanent" classes={{ paper: classes.drawerPaper }}>
<Toolbar />
<div className={classes.drawerContainer}>
<List>
<DrawerItem text="Users" route={`${match.path}/users`} Icon={AccountIcon} />
<DrawerItem text="Roles" route={`${match.path}/roles`} Icon={SecurityIcon} />
<DrawerItem text="Users" route={'users'} Icon={AccountIcon} />
<DrawerItem text="Roles" route={'roles'} Icon={SecurityIcon} />
</List>
</div>
</StyledDrawer>
Expand Down
27 changes: 9 additions & 18 deletions packages/dashboard/src/components/admin/router.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,21 @@
import React from 'react';
import { Redirect, Route, Switch, useRouteMatch } from 'react-router-dom';
import { Route, Routes, Navigate, Outlet } from 'react-router-dom';
import { AdminDrawer } from './drawer';
import { RoleListPage } from './role-list-page';
import { UserListPage } from './user-list-page';
import { UserProfilePage } from './user-profile-page';

export function AdminRouter(): JSX.Element {
const match = useRouteMatch();

return (
<>
<Switch>
<Route path={`${match.path}/users/:user`}>
<UserProfilePage />
</Route>
<Route exact path={`${match.path}/users`}>
<UserListPage />
</Route>
<Route exact path={`${match.path}/roles`}>
<RoleListPage />
</Route>
<Route>
<Redirect to={`${match.path}/users`} />
</Route>
</Switch>
<AdminDrawer />
<Routes>
<Route path={'/*'} element={<Navigate to={'users'} />} />
<Route path={'/users/:username'} element={<UserProfilePage />} />
<Route path={'users'} element={<UserListPage />} />
<Route path={'roles'} element={<RoleListPage />} />
<Route element={<Navigate to={'users'} />} />
</Routes>
<Outlet />
</>
);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,28 @@
import { render, waitFor } from '@testing-library/react';
import { render, waitFor, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react';
import { getActionText, RmfAction } from '../../permissions';
import { PermissionsCard } from '../permissions-card';

// TODO(AA): To remove after
// https://github.com/testing-library/react-testing-library/issues/1216
// has been resolved.
// Workaround for "Warning: An update to ComponentName inside a test was not
// wrapped in act(...)."
const originalError = console.error;
beforeAll(() => {
console.error = (...args) => {
if (/Warning.*not wrapped in act/.test(args[0])) {
return;
}
originalError.call(console, ...args);
};
});

afterAll(() => {
console.error = originalError;
});

describe('PermissionsCard', () => {
it('renders permissions', async () => {
const root = render(
Expand All @@ -25,15 +44,14 @@ describe('PermissionsCard', () => {

it('calls removePermission when button is clicked', async () => {
const removePermission = jest.fn();
const root = render(
const { getByText } = render(
<PermissionsCard
getPermissions={() => [{ action: RmfAction.TaskRead, authz_grp: 'test_group' }]}
removePermission={removePermission}
/>,
);
await waitFor(() => root.getByText('Remove'));
userEvent.click(root.getByText('Remove'));
await waitFor(() => root.getByLabelText('loading'));
await waitFor(() => getByText('Remove'));
fireEvent.click(getByText('Remove'));
expect(removePermission).toHaveBeenCalled();
expect(removePermission.mock.calls[0][0].action).toBe(RmfAction.TaskRead);
expect(removePermission.mock.calls[0][0].authz_grp).toBe('test_group');
Expand Down
11 changes: 3 additions & 8 deletions packages/dashboard/src/components/admin/user-list-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import DeleteIcon from '@mui/icons-material/Delete';
import SearchIcon from '@mui/icons-material/Search';
import React from 'react';
import { ConfirmationDialog, Loading, useAsync } from 'react-components';
import { useHistory, useRouteMatch } from 'react-router';
import { useNavigate } from 'react-router';
import { AppControllerContext } from '../app-contexts';
import { CreateUserDialog, CreateUserDialogProps } from './create-user-dialog';

Expand Down Expand Up @@ -56,8 +56,7 @@ export function UserListCard({
createUser,
}: UserListCardProps): JSX.Element {
const safeAsync = useAsync();
const history = useHistory();
const match = useRouteMatch();
const navigate = useNavigate();
const [users, setUsers] = React.useState<string[]>([]);
const [selectedUser, setSelectedUser] = React.useState<string | null>(null);
const [search, setSearch] = React.useState('');
Expand Down Expand Up @@ -135,11 +134,7 @@ export function UserListCard({
</TableHead>
<TableBody>
{users.map((u) => (
<TableRow
key={u}
className={classes.tableRow}
onClick={() => history.push(`${match.path}/${u}`)}
>
<TableRow key={u} className={classes.tableRow} onClick={() => navigate(`${u}`)}>
<TableCell>{u}</TableCell>
<TableCell>
<Button
Expand Down
11 changes: 5 additions & 6 deletions packages/dashboard/src/components/admin/user-profile-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,33 @@ import { User } from 'api-client';
import { AxiosError } from 'axios';
import React from 'react';
import { useAsync } from 'react-components';
import { useRouteMatch } from 'react-router';
import { useParams } from 'react-router';
import { RmfAppContext } from '../rmf-app';
import { getApiErrorMessage } from '../utils';
import { ManageRolesCard } from './manage-roles-dialog';
import { adminPageClasses, AdminPageContainer } from './page-css';
import { UserProfileCard } from './user-profile';

export function UserProfilePage(): JSX.Element | null {
const match = useRouteMatch<{ user: string }>();
const userId: string | undefined = match.params.user;
const { username } = useParams();
const safeAsync = useAsync();
const { adminApi } = React.useContext(RmfAppContext) || {};
const [user, setUser] = React.useState<User | undefined>(undefined);
const [notFound, setNotFound] = React.useState(false);

const refresh = React.useCallback(() => {
if (!adminApi || !userId) return;
if (!adminApi || !username) return;
(async () => {
try {
setUser((await safeAsync(adminApi.getUserAdminUsersUsernameGet(userId))).data);
setUser((await safeAsync(adminApi.getUserAdminUsersUsernameGet(username))).data);
} catch (e) {
if ((e as AxiosError).response?.status !== 404) {
throw new Error(getApiErrorMessage(e));
}
setNotFound(true);
}
})();
}, [adminApi, safeAsync, userId]);
}, [adminApi, safeAsync, username]);

React.useEffect(() => {
refresh();
Expand Down
Loading

0 comments on commit 22355c1

Please sign in to comment.