Update linter rules
This commit is contained in:
parent
c7b879a5f3
commit
e68de7f432
@ -7,7 +7,8 @@
|
|||||||
"extends": [
|
"extends": [
|
||||||
"eslint:recommended",
|
"eslint:recommended",
|
||||||
"plugin:@typescript-eslint/recommended",
|
"plugin:@typescript-eslint/recommended",
|
||||||
"plugin:react/recommended"
|
"plugin:react/recommended",
|
||||||
|
"plugin:react-hooks/recommended"
|
||||||
],
|
],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaFeatures": {
|
"ecmaFeatures": {
|
||||||
@ -17,7 +18,8 @@
|
|||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"react"
|
"react",
|
||||||
|
"react-hooks"
|
||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"nonblock-statement-body-position": [
|
"nonblock-statement-body-position": [
|
||||||
|
@ -4,14 +4,18 @@ import { Helmet } from 'react-helmet-async';
|
|||||||
// import socket from '../util/Socket';
|
// import socket from '../util/Socket';
|
||||||
|
|
||||||
type SubtitleContext = {
|
type SubtitleContext = {
|
||||||
subtitle: string | null,
|
breadcrumbs: string[],
|
||||||
set: (name: string) => void,
|
set: (name: string) => void,
|
||||||
clear: () => void
|
clear: () => void,
|
||||||
|
push: (crumb: string) => void,
|
||||||
|
pop: () => void,
|
||||||
}
|
}
|
||||||
const Context = React.createContext<SubtitleContext>({
|
const Context = React.createContext<SubtitleContext>({
|
||||||
subtitle: null,
|
breadcrumbs: [],
|
||||||
set: () => null,
|
set: () => null,
|
||||||
clear: () => null
|
clear: () => null,
|
||||||
|
push: () => null,
|
||||||
|
pop: () => null,
|
||||||
});
|
});
|
||||||
|
|
||||||
let TO: NodeJS.Timeout | null = null;
|
let TO: NodeJS.Timeout | null = null;
|
||||||
@ -23,13 +27,14 @@ export const useSubtitle = () =>
|
|||||||
return useContext(Context);
|
return useContext(Context);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Main = ({ title, subtitle, children }: {title: string, subtitle?: string | null, children: React.ReactNode}) =>
|
const Main = ({ title, crumbs: crumbs, children }: {title: string, crumbs: string[], children: React.ReactNode}) =>
|
||||||
{
|
{
|
||||||
|
const trail = crumbs.length ? `/ ${crumbs.join(' / ')}` : '';
|
||||||
return <div className="page">
|
return <div className="page">
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<title>{title} { subtitle ? `/ ${subtitle}` : ''}</title>
|
<title>{title} {trail}</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<h2 className="pageTitle">{title} { subtitle ? `/ ${subtitle}` : ''}</h2>
|
<h2 className="pageTitle">{title} {trail}</h2>
|
||||||
<div className='card'>
|
<div className='card'>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
@ -39,23 +44,42 @@ const Main = ({ title, subtitle, children }: {title: string, subtitle?: string |
|
|||||||
const TitledPage = ({ title, children }: {title: string, children: React.ReactNode}) =>
|
const TitledPage = ({ title, children }: {title: string, children: React.ReactNode}) =>
|
||||||
{
|
{
|
||||||
// let subtitle: string | null = null;
|
// let subtitle: string | null = null;
|
||||||
const [ subtitle, setSubtitle ] = useState<string | null>(null);
|
const [ trail, setTrail ] = useState<string []>([]);
|
||||||
let page = `${title}`;
|
let page = `${title}`;
|
||||||
if (subtitle)
|
if (trail.length)
|
||||||
page += ` / ${subtitle}`;
|
page += ` / ${trail.join(' / ')}`;
|
||||||
const onlineState = { page, url: window.location.href, state: 'Online' };
|
const onlineState = { page, url: window.location.href, state: 'Online' };
|
||||||
const set = (str: string) =>
|
const set = (str: string) =>
|
||||||
{
|
{
|
||||||
// subtitle = str;
|
// subtitle = str;
|
||||||
// console.log('set subtitle', str);
|
// console.log('set subtitle', str);
|
||||||
setSubtitle(() => str);
|
setTrail(() => [ str ]);
|
||||||
};
|
};
|
||||||
|
|
||||||
const clear = () =>
|
const clear = () =>
|
||||||
{
|
{
|
||||||
// subtitle = null;
|
// subtitle = null;
|
||||||
// console.log('clear');
|
// console.log('clear');
|
||||||
setSubtitle(null);
|
setTrail([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const push = (name: string) =>
|
||||||
|
{
|
||||||
|
// console.log('push', name);
|
||||||
|
setTrail(trail =>
|
||||||
|
{
|
||||||
|
return [ ...trail, name ];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const pop = () =>
|
||||||
|
{
|
||||||
|
setTrail(trail =>
|
||||||
|
{
|
||||||
|
trail.pop();
|
||||||
|
// console.log('pop', name);
|
||||||
|
return [ ...trail ];
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const setAfk = () =>
|
const setAfk = () =>
|
||||||
@ -115,10 +139,11 @@ const TitledPage = ({ title, children }: {title: string, children: React.ReactNo
|
|||||||
document.removeEventListener('keypress', activityListener);
|
document.removeEventListener('keypress', activityListener);
|
||||||
document.removeEventListener('visibilitychange', visibilityListener);
|
document.removeEventListener('visibilitychange', visibilityListener);
|
||||||
};
|
};
|
||||||
}, [ title, subtitle ]);
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ title, trail ]);
|
||||||
|
|
||||||
return <Context.Provider value={{ subtitle: null, set, clear }}>
|
return <Context.Provider value={{ breadcrumbs: trail, set, push, pop, clear }}>
|
||||||
<Main title={title} subtitle={subtitle}>
|
<Main title={title} crumbs={trail}>
|
||||||
{children}
|
{children}
|
||||||
</Main>
|
</Main>
|
||||||
</Context.Provider>;
|
</Context.Provider>;
|
||||||
|
@ -47,6 +47,7 @@ const Admin = () =>
|
|||||||
{
|
{
|
||||||
if(window.location.href.endsWith('/admin'))
|
if(window.location.href.endsWith('/admin'))
|
||||||
subtitle.clear();
|
subtitle.clear();
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [ window.location.href ]);
|
}, [ window.location.href ]);
|
||||||
return <ErrorBoundary>
|
return <ErrorBoundary>
|
||||||
<Routes>
|
<Routes>
|
||||||
|
@ -33,24 +33,23 @@ const Role = ({ refreshList }: RoleProps) =>
|
|||||||
const [ role, setRole ] = useState<RoleStruct | null>(roleId ? roles.get(roleId) ?? null : null);
|
const [ role, setRole ] = useState<RoleStruct | null>(roleId ? roles.get(roleId) ?? null : null);
|
||||||
const [ refresh, setRefresh ] = useState(false);
|
const [ refresh, setRefresh ] = useState(false);
|
||||||
|
|
||||||
if (!roleId)
|
|
||||||
return <div>
|
|
||||||
<BackButton />
|
|
||||||
<p>Invalid userId</p>
|
|
||||||
</div>;
|
|
||||||
|
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if (!role)
|
if (!role)
|
||||||
(async () =>
|
(async () =>
|
||||||
{
|
{
|
||||||
const response = await get(`/api/roles/${roleId}`);
|
const response = await get<RoleStruct>(`/api/roles/${roleId}`);
|
||||||
if (!response.success || !response.data)
|
if (!response.success || !response.data)
|
||||||
return errorToast(response.message);
|
return errorToast(response.message);
|
||||||
setRole(response.data as RoleStruct);
|
setRole(response.data);
|
||||||
})();
|
})();
|
||||||
}, [ roleId ]);
|
}, [ role, roleId ]);
|
||||||
|
|
||||||
|
if (!roleId)
|
||||||
|
return <div>
|
||||||
|
<BackButton />
|
||||||
|
<p>Invalid userId</p>
|
||||||
|
</div>;
|
||||||
|
|
||||||
if (!role)
|
if (!role)
|
||||||
return <div>
|
return <div>
|
||||||
@ -308,7 +307,7 @@ const Main = () =>
|
|||||||
setRoles(new Map(response.data.roles.map((role) => [ role.id, role ])));
|
setRoles(new Map(response.data.roles.map((role) => [ role.id, role ])));
|
||||||
setLoadState(RefresherState.success);
|
setLoadState(RefresherState.success);
|
||||||
})();
|
})();
|
||||||
}, [ page, filters, refresh ]);
|
}, [ page, filters, refresh, setRoles ]);
|
||||||
|
|
||||||
return <Routes>
|
return <Routes>
|
||||||
<Route path='/*' element={<RoleList {...{ page, pages, setPage, loadState, filterUpdate: setFilters, onRefresh: () => setRefresh(val => !val) }} />} />
|
<Route path='/*' element={<RoleList {...{ page, pages, setPage, loadState, filterUpdate: setFilters, onRefresh: () => setRefresh(val => !val) }} />} />
|
||||||
@ -322,7 +321,8 @@ const Roles = () =>
|
|||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
subtitle.set('Roles');
|
subtitle.set('Roles');
|
||||||
});
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [ ]);
|
||||||
return <ErrorBoundary>
|
return <ErrorBoundary>
|
||||||
<RolesContext>
|
<RolesContext>
|
||||||
<Main />
|
<Main />
|
||||||
|
@ -359,16 +359,11 @@ type UserProps = {
|
|||||||
}
|
}
|
||||||
const User = ({ refreshList }: UserProps) =>
|
const User = ({ refreshList }: UserProps) =>
|
||||||
{
|
{
|
||||||
|
// const subtitle = useSubtitle();
|
||||||
const { users, refreshState } = useContext(Context);
|
const { users, refreshState } = useContext(Context);
|
||||||
const { userId } = useParams();
|
const { userId } = useParams();
|
||||||
|
|
||||||
if (!userId)
|
const [ user, setUser ] = useState<UserStruct | null>(users.get(userId ?? '') ?? null);
|
||||||
return <div>
|
|
||||||
<BackButton />
|
|
||||||
<p>Invalid userId</p>
|
|
||||||
</div>;
|
|
||||||
|
|
||||||
const [ user, setUser ] = useState<UserStruct | null>(users.get(userId) ?? null);
|
|
||||||
const [ applications, setApplications ] = useState<Map<string, ApplicationStruct>>(new Map());
|
const [ applications, setApplications ] = useState<Map<string, ApplicationStruct>>(new Map());
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
@ -376,12 +371,18 @@ const User = ({ refreshList }: UserProps) =>
|
|||||||
if (!user)
|
if (!user)
|
||||||
(async () =>
|
(async () =>
|
||||||
{
|
{
|
||||||
const response = await get(`/api/users/${userId}`);
|
const response = await get<UserStruct>(`/api/users/${userId}`);
|
||||||
if (!response.success || !response.data)
|
if (!response.success || !response.data)
|
||||||
return errorToast(response.message);
|
return errorToast(response.message);
|
||||||
setUser(response.data as UserStruct);
|
setUser(response.data);
|
||||||
})();
|
})();
|
||||||
}, [ userId, refreshState ]);
|
}, [ userId, refreshState, user ]);
|
||||||
|
|
||||||
|
if (!userId)
|
||||||
|
return <div>
|
||||||
|
<BackButton />
|
||||||
|
<p>Invalid userId</p>
|
||||||
|
</div>;
|
||||||
|
|
||||||
return <Routes>
|
return <Routes>
|
||||||
<Route path='/' element={<UserData user={user} updateUser={(user) =>
|
<Route path='/' element={<UserData user={user} updateUser={(user) =>
|
||||||
@ -543,7 +544,7 @@ const Main = () =>
|
|||||||
setUsers(new Map(response.data.users.map((user) => [ user.id, user ])));
|
setUsers(new Map(response.data.users.map((user) => [ user.id, user ])));
|
||||||
setLoadState(RefresherState.success);
|
setLoadState(RefresherState.success);
|
||||||
})();
|
})();
|
||||||
}, [ page, searchFilter, refresh ]);
|
}, [ page, searchFilter, refresh, setUsers ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
@ -554,7 +555,7 @@ const Main = () =>
|
|||||||
return errorToast(response.message);
|
return errorToast(response.message);
|
||||||
setRoles(new Map(response.data.roles.map((role) => [ role.id, role ])));
|
setRoles(new Map(response.data.roles.map((role) => [ role.id, role ])));
|
||||||
})();
|
})();
|
||||||
}, [ refresh ]);
|
}, [ refresh, setRoles ]);
|
||||||
|
|
||||||
return <Routes>
|
return <Routes>
|
||||||
<Route path='/*' element={<UserList {...{ page, pages, setPage, loadState, onRefresh: () => setRefresh(val => !val) }} />} />
|
<Route path='/*' element={<UserList {...{ page, pages, setPage, loadState, onRefresh: () => setRefresh(val => !val) }} />} />
|
||||||
@ -569,7 +570,8 @@ const Users = () =>
|
|||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
subtitle.set('Users');
|
subtitle.set('Users');
|
||||||
});
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
return <ErrorBoundary>
|
return <ErrorBoundary>
|
||||||
<UsersContext>
|
<UsersContext>
|
||||||
<Main/>
|
<Main/>
|
||||||
|
Loading…
Reference in New Issue
Block a user