Skip to content
This repository has been archived by the owner on Oct 27, 2022. It is now read-only.

Commit

Permalink
refactor: misc type improvements (#945)
Browse files Browse the repository at this point in the history
* refactor: improve ChangePassword types

* refactor: improve usePagination types

* refactor: improve UsersList types
  • Loading branch information
olav authored May 4, 2022
1 parent d2fcb49 commit 31d32d2
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -1,78 +1,69 @@
import { useState } from 'react';
import React, { useState } from 'react';
import classnames from 'classnames';
import { Avatar, TextField, Typography } from '@mui/material';
import { Avatar, TextField, Typography, Alert } from '@mui/material';
import { trim } from 'component/common/util';
import { modalStyles } from 'component/admin/users/util';
import { Dialogue } from 'component/common/Dialogue/Dialogue';
import PasswordChecker from 'component/user/common/ResetPasswordForm/PasswordChecker/PasswordChecker';
import { useThemeStyles } from 'themes/themeStyles';
import PasswordMatcher from 'component/user/common/ResetPasswordForm/PasswordMatcher/PasswordMatcher';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { Alert } from '@mui/material';
import { IUser } from 'interfaces/user';

interface IChangePasswordProps {
showDialog: boolean;
closeDialog: () => void;
changePassword: (user: IUser, password: string) => Promise<Response>;
user: Partial<IUser>;
changePassword: (userId: number, password: string) => Promise<Response>;
user: IUser;
}

const ChangePassword = ({
showDialog,
closeDialog,
changePassword,
user = {},
user,
}: IChangePasswordProps) => {
const [data, setData] = useState({});
const [data, setData] = useState<Record<string, string>>({});
const [error, setError] = useState<Record<string, string>>({});
const [validPassword, setValidPassword] = useState(false);
const { classes: themeStyles } = useThemeStyles();

// @ts-expect-error
const updateField = e => {
const updateField: React.ChangeEventHandler<HTMLInputElement> = event => {
setError({});
setData({
...data,
[e.target.name]: trim(e.target.value),
});
setData({ ...data, [event.target.name]: trim(event.target.value) });
};

// @ts-expect-error
const submit = async e => {
e.preventDefault();
const submit = async (event: React.SyntheticEvent) => {
event.preventDefault();

if (!validPassword) {
// @ts-expect-error
if (!data.password || data.password.length < 8) {
setError({
password:
'You must specify a password with at least 8 chars.',
});
return;
}
// @ts-expect-error
if (!(data.password === data.confirm)) {
setError({ confirm: 'Passwords does not match' });
return;
}
}

try {
// @ts-expect-error
await changePassword(user, data.password);
await changePassword(user.id, data.password);
setData({});
closeDialog();
} catch (error) {
// @ts-expect-error
const msg = error.message || 'Could not update password';
} catch (error: unknown) {
const msg =
(error instanceof Error && error.message) ||
'Could not update password';
setError({ general: msg });
}
};

// @ts-expect-error
const onCancel = e => {
e.preventDefault();
const onCancel = (event: React.SyntheticEvent) => {
event.preventDefault();
setData({});
closeDialog();
};
Expand Down Expand Up @@ -118,15 +109,13 @@ const ChangePassword = ({
</Typography>
</div>
<PasswordChecker
// @ts-expect-error
password={data.password}
callback={setValidPassword}
/>
<TextField
label="New password"
name="password"
type="password"
// @ts-expect-error
value={data.password}
helperText={error.password}
onChange={updateField}
Expand All @@ -137,7 +126,6 @@ const ChangePassword = ({
label="Confirm password"
name="confirm"
type="password"
// @ts-expect-error
value={data.confirm}
error={error.confirm !== undefined}
helperText={error.confirm}
Expand All @@ -146,9 +134,7 @@ const ChangePassword = ({
size="small"
/>
<PasswordMatcher
// @ts-expect-error
started={data.password && data.confirm}
// @ts-expect-error
started={Boolean(data.password && data.confirm)}
matchingPasswords={data.password === data.confirm}
/>
</form>
Expand Down
38 changes: 16 additions & 22 deletions src/component/admin/users/UsersList/UsersList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,8 @@ const UsersList = ({ search }: IUsersListProps) => {
const { classes: styles } = useStyles();
const { users, roles, refetch, loading } = useUsers();
const { setToastData, setToastApiError } = useToast();
const {
removeUser,
changePassword,
validatePassword,
userLoading,
userApiErrors,
} = useAdminUsersApi();
const { removeUser, changePassword, userLoading, userApiErrors } =
useAdminUsersApi();
const { hasAccess } = useContext(AccessContext);
const { locationSettings } = useLocationSettings();
const [pwDialog, setPwDialog] = useState<{ open: boolean; user?: IUser }>({
Expand Down Expand Up @@ -87,12 +82,11 @@ const UsersList = ({ search }: IUsersListProps) => {
setPwDialog({ open: false });
};

const onDeleteUser = async () => {
const onDeleteUser = async (user: IUser) => {
try {
// @ts-expect-error
await removeUser(delUser);
await removeUser(user.id);
setToastData({
title: `${delUser?.name} has been deleted`,
title: `${user.name} has been deleted`,
type: 'success',
});
refetch();
Expand Down Expand Up @@ -131,7 +125,6 @@ const UsersList = ({ search }: IUsersListProps) => {
return page.map(user => {
return (
<UserListItem
// @ts-expect-error
key={user.id}
user={user}
openPwDialog={openPwDialog}
Expand Down Expand Up @@ -224,24 +217,25 @@ const UsersList = ({ search }: IUsersListProps) => {
inviteLink={inviteLink}
/>

<ChangePassword
showDialog={pwDialog.open}
closeDialog={closePwDialog}
// @ts-expect-error
changePassword={changePassword}
validatePassword={validatePassword}
// @ts-expect-error
user={pwDialog.user}
<ConditionallyRender
condition={Boolean(pwDialog.user)}
show={() => (
<ChangePassword
showDialog={pwDialog.open}
closeDialog={closePwDialog}
changePassword={changePassword}
user={pwDialog.user!}
/>
)}
/>

<ConditionallyRender
condition={Boolean(delUser)}
show={
<DeleteUser
showDialog={delDialog}
closeDialog={closeDelDialog}
user={delUser!}
removeUser={onDeleteUser}
removeUser={() => onDeleteUser(delUser!)}
userLoading={userLoading}
userApiErrors={userApiErrors}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,12 @@ import { useStyles } from './FeatureToggleListNew.styles';
import FeatureToggleListNewItem from './FeatureToggleListNewItem/FeatureToggleListNewItem';
import usePagination from 'hooks/usePagination';
import loadingFeatures from './FeatureToggleListNewItem/loadingFeatures';
import {
IFeatureToggle,
IFeatureToggleListItem,
} from 'interfaces/featureToggle';
import { IFeatureToggleListItem } from 'interfaces/featureToggle';
import PaginateUI from 'component/common/PaginateUI/PaginateUI';
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
import { createGlobalStateHook } from 'hooks/useGlobalState';
import { AnnouncerContext } from 'component/common/Announcer/AnnouncerContext/AnnouncerContext';

interface IFeatureToggleListNewProps {
features: IFeatureToggleListItem[];
loading: boolean;
Expand Down Expand Up @@ -86,9 +84,10 @@ const FeatureToggleListNew = ({
const { classes: styles } = useStyles();
const { setAnnouncement } = useContext(AnnouncerContext);
const [sortOpt, setSortOpt] = useFeatureToggLeProjectSort();
const [sortedFeatures, setSortedFeatures] = useState(
sortList([...features], sortOpt)
);

const [sortedFeatures, setSortedFeatures] = useState<
IFeatureToggleListItem[]
>(sortList([...features], sortOpt));

const { page, pages, nextPage, prevPage, setPageIndex, pageIndex } =
usePagination(sortedFeatures, 50);
Expand Down Expand Up @@ -156,7 +155,7 @@ const FeatureToggleListNew = ({
});
}

return page.map((feature: IFeatureToggle) => {
return page.map((feature: IFeatureToggleListItem) => {
return (
<FeatureToggleListNewItem
key={feature.name}
Expand Down
12 changes: 5 additions & 7 deletions src/hooks/api/actions/useAdminUsersApi/useAdminUsersApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,11 @@ const useAdminUsersApi = () => {
return makeRequest(req.caller, req.id);
};

const removeUser = async (user: IUserPayload) => {
const removeUser = async (userId: number) => {
const requestId = 'removeUser';
const req = createRequest(
`api/admin/user-admin/${user.id}`,
{
method: 'DELETE',
},
`api/admin/user-admin/${userId}`,
{ method: 'DELETE' },
requestId
);

Expand All @@ -63,10 +61,10 @@ const useAdminUsersApi = () => {
return makeRequest(req.caller, req.id);
};

const changePassword = async (user: IUserPayload, password: string) => {
const changePassword = async (userId: number, password: string) => {
const requestId = 'changePassword';
const req = createRequest(
`api/admin/user-admin/${user.id}/change-password`,
`api/admin/user-admin/${userId}/change-password`,
{
method: 'POST',
body: JSON.stringify({ password }),
Expand Down
10 changes: 5 additions & 5 deletions src/hooks/usePagination.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useEffect, useState } from 'react';
import { paginate } from '../utils/paginate';
import { paginate } from 'utils/paginate';

const usePagination = (
data: any[],
const usePagination = <T>(
data: T[],
limit: number,
filterFunc?: (item: any) => boolean
filterFunc?: (item: T) => boolean
) => {
const [paginatedData, setPaginatedData] = useState([[]]);
const [paginatedData, setPaginatedData] = useState<T[][]>([[]]);
const [pageIndex, setPageIndex] = useState(0);

useEffect(() => {
Expand Down

0 comments on commit 31d32d2

Please sign in to comment.