mirror of
https://github.com/Unleash/unleash.git
synced 2025-02-19 00:15:43 +01:00
refactor: misc type improvements (#945)
* refactor: improve ChangePassword types * refactor: improve usePagination types * refactor: improve UsersList types
This commit is contained in:
parent
73d2b73955
commit
7b60ef2aa6
@ -1,6 +1,6 @@
|
|||||||
import { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import classnames from 'classnames';
|
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 { trim } from 'component/common/util';
|
||||||
import { modalStyles } from 'component/admin/users/util';
|
import { modalStyles } from 'component/admin/users/util';
|
||||||
import { Dialogue } from 'component/common/Dialogue/Dialogue';
|
import { Dialogue } from 'component/common/Dialogue/Dialogue';
|
||||||
@ -8,42 +8,35 @@ import PasswordChecker from 'component/user/common/ResetPasswordForm/PasswordChe
|
|||||||
import { useThemeStyles } from 'themes/themeStyles';
|
import { useThemeStyles } from 'themes/themeStyles';
|
||||||
import PasswordMatcher from 'component/user/common/ResetPasswordForm/PasswordMatcher/PasswordMatcher';
|
import PasswordMatcher from 'component/user/common/ResetPasswordForm/PasswordMatcher/PasswordMatcher';
|
||||||
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
|
||||||
import { Alert } from '@mui/material';
|
|
||||||
import { IUser } from 'interfaces/user';
|
import { IUser } from 'interfaces/user';
|
||||||
|
|
||||||
interface IChangePasswordProps {
|
interface IChangePasswordProps {
|
||||||
showDialog: boolean;
|
showDialog: boolean;
|
||||||
closeDialog: () => void;
|
closeDialog: () => void;
|
||||||
changePassword: (user: IUser, password: string) => Promise<Response>;
|
changePassword: (userId: number, password: string) => Promise<Response>;
|
||||||
user: Partial<IUser>;
|
user: IUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ChangePassword = ({
|
const ChangePassword = ({
|
||||||
showDialog,
|
showDialog,
|
||||||
closeDialog,
|
closeDialog,
|
||||||
changePassword,
|
changePassword,
|
||||||
user = {},
|
user,
|
||||||
}: IChangePasswordProps) => {
|
}: IChangePasswordProps) => {
|
||||||
const [data, setData] = useState({});
|
const [data, setData] = useState<Record<string, string>>({});
|
||||||
const [error, setError] = useState<Record<string, string>>({});
|
const [error, setError] = useState<Record<string, string>>({});
|
||||||
const [validPassword, setValidPassword] = useState(false);
|
const [validPassword, setValidPassword] = useState(false);
|
||||||
const { classes: themeStyles } = useThemeStyles();
|
const { classes: themeStyles } = useThemeStyles();
|
||||||
|
|
||||||
// @ts-expect-error
|
const updateField: React.ChangeEventHandler<HTMLInputElement> = event => {
|
||||||
const updateField = e => {
|
|
||||||
setError({});
|
setError({});
|
||||||
setData({
|
setData({ ...data, [event.target.name]: trim(event.target.value) });
|
||||||
...data,
|
|
||||||
[e.target.name]: trim(e.target.value),
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// @ts-expect-error
|
const submit = async (event: React.SyntheticEvent) => {
|
||||||
const submit = async e => {
|
event.preventDefault();
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
if (!validPassword) {
|
if (!validPassword) {
|
||||||
// @ts-expect-error
|
|
||||||
if (!data.password || data.password.length < 8) {
|
if (!data.password || data.password.length < 8) {
|
||||||
setError({
|
setError({
|
||||||
password:
|
password:
|
||||||
@ -51,7 +44,6 @@ const ChangePassword = ({
|
|||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// @ts-expect-error
|
|
||||||
if (!(data.password === data.confirm)) {
|
if (!(data.password === data.confirm)) {
|
||||||
setError({ confirm: 'Passwords does not match' });
|
setError({ confirm: 'Passwords does not match' });
|
||||||
return;
|
return;
|
||||||
@ -59,20 +51,19 @@ const ChangePassword = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// @ts-expect-error
|
await changePassword(user.id, data.password);
|
||||||
await changePassword(user, data.password);
|
|
||||||
setData({});
|
setData({});
|
||||||
closeDialog();
|
closeDialog();
|
||||||
} catch (error) {
|
} catch (error: unknown) {
|
||||||
// @ts-expect-error
|
const msg =
|
||||||
const msg = error.message || 'Could not update password';
|
(error instanceof Error && error.message) ||
|
||||||
|
'Could not update password';
|
||||||
setError({ general: msg });
|
setError({ general: msg });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// @ts-expect-error
|
const onCancel = (event: React.SyntheticEvent) => {
|
||||||
const onCancel = e => {
|
event.preventDefault();
|
||||||
e.preventDefault();
|
|
||||||
setData({});
|
setData({});
|
||||||
closeDialog();
|
closeDialog();
|
||||||
};
|
};
|
||||||
@ -118,7 +109,6 @@ const ChangePassword = ({
|
|||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
<PasswordChecker
|
<PasswordChecker
|
||||||
// @ts-expect-error
|
|
||||||
password={data.password}
|
password={data.password}
|
||||||
callback={setValidPassword}
|
callback={setValidPassword}
|
||||||
/>
|
/>
|
||||||
@ -126,7 +116,6 @@ const ChangePassword = ({
|
|||||||
label="New password"
|
label="New password"
|
||||||
name="password"
|
name="password"
|
||||||
type="password"
|
type="password"
|
||||||
// @ts-expect-error
|
|
||||||
value={data.password}
|
value={data.password}
|
||||||
helperText={error.password}
|
helperText={error.password}
|
||||||
onChange={updateField}
|
onChange={updateField}
|
||||||
@ -137,7 +126,6 @@ const ChangePassword = ({
|
|||||||
label="Confirm password"
|
label="Confirm password"
|
||||||
name="confirm"
|
name="confirm"
|
||||||
type="password"
|
type="password"
|
||||||
// @ts-expect-error
|
|
||||||
value={data.confirm}
|
value={data.confirm}
|
||||||
error={error.confirm !== undefined}
|
error={error.confirm !== undefined}
|
||||||
helperText={error.confirm}
|
helperText={error.confirm}
|
||||||
@ -146,9 +134,7 @@ const ChangePassword = ({
|
|||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
<PasswordMatcher
|
<PasswordMatcher
|
||||||
// @ts-expect-error
|
started={Boolean(data.password && data.confirm)}
|
||||||
started={data.password && data.confirm}
|
|
||||||
// @ts-expect-error
|
|
||||||
matchingPasswords={data.password === data.confirm}
|
matchingPasswords={data.password === data.confirm}
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
@ -39,13 +39,8 @@ const UsersList = ({ search }: IUsersListProps) => {
|
|||||||
const { classes: styles } = useStyles();
|
const { classes: styles } = useStyles();
|
||||||
const { users, roles, refetch, loading } = useUsers();
|
const { users, roles, refetch, loading } = useUsers();
|
||||||
const { setToastData, setToastApiError } = useToast();
|
const { setToastData, setToastApiError } = useToast();
|
||||||
const {
|
const { removeUser, changePassword, userLoading, userApiErrors } =
|
||||||
removeUser,
|
useAdminUsersApi();
|
||||||
changePassword,
|
|
||||||
validatePassword,
|
|
||||||
userLoading,
|
|
||||||
userApiErrors,
|
|
||||||
} = useAdminUsersApi();
|
|
||||||
const { hasAccess } = useContext(AccessContext);
|
const { hasAccess } = useContext(AccessContext);
|
||||||
const { locationSettings } = useLocationSettings();
|
const { locationSettings } = useLocationSettings();
|
||||||
const [pwDialog, setPwDialog] = useState<{ open: boolean; user?: IUser }>({
|
const [pwDialog, setPwDialog] = useState<{ open: boolean; user?: IUser }>({
|
||||||
@ -87,12 +82,11 @@ const UsersList = ({ search }: IUsersListProps) => {
|
|||||||
setPwDialog({ open: false });
|
setPwDialog({ open: false });
|
||||||
};
|
};
|
||||||
|
|
||||||
const onDeleteUser = async () => {
|
const onDeleteUser = async (user: IUser) => {
|
||||||
try {
|
try {
|
||||||
// @ts-expect-error
|
await removeUser(user.id);
|
||||||
await removeUser(delUser);
|
|
||||||
setToastData({
|
setToastData({
|
||||||
title: `${delUser?.name} has been deleted`,
|
title: `${user.name} has been deleted`,
|
||||||
type: 'success',
|
type: 'success',
|
||||||
});
|
});
|
||||||
refetch();
|
refetch();
|
||||||
@ -131,7 +125,6 @@ const UsersList = ({ search }: IUsersListProps) => {
|
|||||||
return page.map(user => {
|
return page.map(user => {
|
||||||
return (
|
return (
|
||||||
<UserListItem
|
<UserListItem
|
||||||
// @ts-expect-error
|
|
||||||
key={user.id}
|
key={user.id}
|
||||||
user={user}
|
user={user}
|
||||||
openPwDialog={openPwDialog}
|
openPwDialog={openPwDialog}
|
||||||
@ -224,16 +217,17 @@ const UsersList = ({ search }: IUsersListProps) => {
|
|||||||
inviteLink={inviteLink}
|
inviteLink={inviteLink}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ChangePassword
|
<ConditionallyRender
|
||||||
showDialog={pwDialog.open}
|
condition={Boolean(pwDialog.user)}
|
||||||
closeDialog={closePwDialog}
|
show={() => (
|
||||||
// @ts-expect-error
|
<ChangePassword
|
||||||
changePassword={changePassword}
|
showDialog={pwDialog.open}
|
||||||
validatePassword={validatePassword}
|
closeDialog={closePwDialog}
|
||||||
// @ts-expect-error
|
changePassword={changePassword}
|
||||||
user={pwDialog.user}
|
user={pwDialog.user!}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ConditionallyRender
|
<ConditionallyRender
|
||||||
condition={Boolean(delUser)}
|
condition={Boolean(delUser)}
|
||||||
show={
|
show={
|
||||||
@ -241,7 +235,7 @@ const UsersList = ({ search }: IUsersListProps) => {
|
|||||||
showDialog={delDialog}
|
showDialog={delDialog}
|
||||||
closeDialog={closeDelDialog}
|
closeDialog={closeDelDialog}
|
||||||
user={delUser!}
|
user={delUser!}
|
||||||
removeUser={onDeleteUser}
|
removeUser={() => onDeleteUser(delUser!)}
|
||||||
userLoading={userLoading}
|
userLoading={userLoading}
|
||||||
userApiErrors={userApiErrors}
|
userApiErrors={userApiErrors}
|
||||||
/>
|
/>
|
||||||
|
@ -11,14 +11,12 @@ import { useStyles } from './FeatureToggleListNew.styles';
|
|||||||
import FeatureToggleListNewItem from './FeatureToggleListNewItem/FeatureToggleListNewItem';
|
import FeatureToggleListNewItem from './FeatureToggleListNewItem/FeatureToggleListNewItem';
|
||||||
import usePagination from 'hooks/usePagination';
|
import usePagination from 'hooks/usePagination';
|
||||||
import loadingFeatures from './FeatureToggleListNewItem/loadingFeatures';
|
import loadingFeatures from './FeatureToggleListNewItem/loadingFeatures';
|
||||||
import {
|
import { IFeatureToggleListItem } from 'interfaces/featureToggle';
|
||||||
IFeatureToggle,
|
|
||||||
IFeatureToggleListItem,
|
|
||||||
} from 'interfaces/featureToggle';
|
|
||||||
import PaginateUI from 'component/common/PaginateUI/PaginateUI';
|
import PaginateUI from 'component/common/PaginateUI/PaginateUI';
|
||||||
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
|
import StringTruncator from 'component/common/StringTruncator/StringTruncator';
|
||||||
import { createGlobalStateHook } from 'hooks/useGlobalState';
|
import { createGlobalStateHook } from 'hooks/useGlobalState';
|
||||||
import { AnnouncerContext } from 'component/common/Announcer/AnnouncerContext/AnnouncerContext';
|
import { AnnouncerContext } from 'component/common/Announcer/AnnouncerContext/AnnouncerContext';
|
||||||
|
|
||||||
interface IFeatureToggleListNewProps {
|
interface IFeatureToggleListNewProps {
|
||||||
features: IFeatureToggleListItem[];
|
features: IFeatureToggleListItem[];
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
@ -86,9 +84,10 @@ const FeatureToggleListNew = ({
|
|||||||
const { classes: styles } = useStyles();
|
const { classes: styles } = useStyles();
|
||||||
const { setAnnouncement } = useContext(AnnouncerContext);
|
const { setAnnouncement } = useContext(AnnouncerContext);
|
||||||
const [sortOpt, setSortOpt] = useFeatureToggLeProjectSort();
|
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 } =
|
const { page, pages, nextPage, prevPage, setPageIndex, pageIndex } =
|
||||||
usePagination(sortedFeatures, 50);
|
usePagination(sortedFeatures, 50);
|
||||||
@ -156,7 +155,7 @@ const FeatureToggleListNew = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return page.map((feature: IFeatureToggle) => {
|
return page.map((feature: IFeatureToggleListItem) => {
|
||||||
return (
|
return (
|
||||||
<FeatureToggleListNewItem
|
<FeatureToggleListNewItem
|
||||||
key={feature.name}
|
key={feature.name}
|
||||||
|
@ -36,13 +36,11 @@ const useAdminUsersApi = () => {
|
|||||||
return makeRequest(req.caller, req.id);
|
return makeRequest(req.caller, req.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeUser = async (user: IUserPayload) => {
|
const removeUser = async (userId: number) => {
|
||||||
const requestId = 'removeUser';
|
const requestId = 'removeUser';
|
||||||
const req = createRequest(
|
const req = createRequest(
|
||||||
`api/admin/user-admin/${user.id}`,
|
`api/admin/user-admin/${userId}`,
|
||||||
{
|
{ method: 'DELETE' },
|
||||||
method: 'DELETE',
|
|
||||||
},
|
|
||||||
requestId
|
requestId
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -63,10 +61,10 @@ const useAdminUsersApi = () => {
|
|||||||
return makeRequest(req.caller, req.id);
|
return makeRequest(req.caller, req.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const changePassword = async (user: IUserPayload, password: string) => {
|
const changePassword = async (userId: number, password: string) => {
|
||||||
const requestId = 'changePassword';
|
const requestId = 'changePassword';
|
||||||
const req = createRequest(
|
const req = createRequest(
|
||||||
`api/admin/user-admin/${user.id}/change-password`,
|
`api/admin/user-admin/${userId}/change-password`,
|
||||||
{
|
{
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({ password }),
|
body: JSON.stringify({ password }),
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { paginate } from '../utils/paginate';
|
import { paginate } from 'utils/paginate';
|
||||||
|
|
||||||
const usePagination = (
|
const usePagination = <T>(
|
||||||
data: any[],
|
data: T[],
|
||||||
limit: number,
|
limit: number,
|
||||||
filterFunc?: (item: any) => boolean
|
filterFunc?: (item: T) => boolean
|
||||||
) => {
|
) => {
|
||||||
const [paginatedData, setPaginatedData] = useState([[]]);
|
const [paginatedData, setPaginatedData] = useState<T[][]>([[]]);
|
||||||
const [pageIndex, setPageIndex] = useState(0);
|
const [pageIndex, setPageIndex] = useState(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
Loading…
Reference in New Issue
Block a user