Update linter rules

This commit is contained in:
Erik 2024-04-06 12:55:26 +03:00
parent c7b879a5f3
commit e68de7f432
5 changed files with 72 additions and 42 deletions

View File

@ -7,7 +7,8 @@
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended"
"plugin:react/recommended",
"plugin:react-hooks/recommended"
],
"parserOptions": {
"ecmaFeatures": {
@ -17,7 +18,8 @@
"sourceType": "module"
},
"plugins": [
"react"
"react",
"react-hooks"
],
"rules": {
"nonblock-statement-body-position": [

View File

@ -4,14 +4,18 @@ import { Helmet } from 'react-helmet-async';
// import socket from '../util/Socket';
type SubtitleContext = {
subtitle: string | null,
breadcrumbs: string[],
set: (name: string) => void,
clear: () => void
clear: () => void,
push: (crumb: string) => void,
pop: () => void,
}
const Context = React.createContext<SubtitleContext>({
subtitle: null,
breadcrumbs: [],
set: () => null,
clear: () => null
clear: () => null,
push: () => null,
pop: () => null,
});
let TO: NodeJS.Timeout | null = null;
@ -23,13 +27,14 @@ export const useSubtitle = () =>
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">
<Helmet>
<title>{title} { subtitle ? `/ ${subtitle}` : ''}</title>
<title>{title} {trail}</title>
</Helmet>
<h2 className="pageTitle">{title} { subtitle ? `/ ${subtitle}` : ''}</h2>
<h2 className="pageTitle">{title} {trail}</h2>
<div className='card'>
{children}
</div>
@ -39,23 +44,42 @@ const Main = ({ title, subtitle, children }: {title: string, subtitle?: string |
const TitledPage = ({ title, children }: {title: string, children: React.ReactNode}) =>
{
// let subtitle: string | null = null;
const [ subtitle, setSubtitle ] = useState<string | null>(null);
const [ trail, setTrail ] = useState<string []>([]);
let page = `${title}`;
if (subtitle)
page += ` / ${subtitle}`;
if (trail.length)
page += ` / ${trail.join(' / ')}`;
const onlineState = { page, url: window.location.href, state: 'Online' };
const set = (str: string) =>
{
// subtitle = str;
// console.log('set subtitle', str);
setSubtitle(() => str);
setTrail(() => [ str ]);
};
const clear = () =>
{
// subtitle = null;
// 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 = () =>
@ -115,10 +139,11 @@ const TitledPage = ({ title, children }: {title: string, children: React.ReactNo
document.removeEventListener('keypress', activityListener);
document.removeEventListener('visibilitychange', visibilityListener);
};
}, [ title, subtitle ]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ title, trail ]);
return <Context.Provider value={{ subtitle: null, set, clear }}>
<Main title={title} subtitle={subtitle}>
return <Context.Provider value={{ breadcrumbs: trail, set, push, pop, clear }}>
<Main title={title} crumbs={trail}>
{children}
</Main>
</Context.Provider>;

View File

@ -47,6 +47,7 @@ const Admin = () =>
{
if(window.location.href.endsWith('/admin'))
subtitle.clear();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ window.location.href ]);
return <ErrorBoundary>
<Routes>

View File

@ -33,24 +33,23 @@ const Role = ({ refreshList }: RoleProps) =>
const [ role, setRole ] = useState<RoleStruct | null>(roleId ? roles.get(roleId) ?? null : null);
const [ refresh, setRefresh ] = useState(false);
if (!roleId)
return <div>
<BackButton />
<p>Invalid userId</p>
</div>;
useEffect(() =>
{
if (!role)
(async () =>
{
const response = await get(`/api/roles/${roleId}`);
const response = await get<RoleStruct>(`/api/roles/${roleId}`);
if (!response.success || !response.data)
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)
return <div>
@ -308,7 +307,7 @@ const Main = () =>
setRoles(new Map(response.data.roles.map((role) => [ role.id, role ])));
setLoadState(RefresherState.success);
})();
}, [ page, filters, refresh ]);
}, [ page, filters, refresh, setRoles ]);
return <Routes>
<Route path='/*' element={<RoleList {...{ page, pages, setPage, loadState, filterUpdate: setFilters, onRefresh: () => setRefresh(val => !val) }} />} />
@ -322,7 +321,8 @@ const Roles = () =>
useEffect(() =>
{
subtitle.set('Roles');
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ ]);
return <ErrorBoundary>
<RolesContext>
<Main />

View File

@ -359,16 +359,11 @@ type UserProps = {
}
const User = ({ refreshList }: UserProps) =>
{
// const subtitle = useSubtitle();
const { users, refreshState } = useContext(Context);
const { userId } = useParams();
if (!userId)
return <div>
<BackButton />
<p>Invalid userId</p>
</div>;
const [ user, setUser ] = useState<UserStruct | null>(users.get(userId) ?? null);
const [ user, setUser ] = useState<UserStruct | null>(users.get(userId ?? '') ?? null);
const [ applications, setApplications ] = useState<Map<string, ApplicationStruct>>(new Map());
useEffect(() =>
@ -376,12 +371,18 @@ const User = ({ refreshList }: UserProps) =>
if (!user)
(async () =>
{
const response = await get(`/api/users/${userId}`);
const response = await get<UserStruct>(`/api/users/${userId}`);
if (!response.success || !response.data)
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>
<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 ])));
setLoadState(RefresherState.success);
})();
}, [ page, searchFilter, refresh ]);
}, [ page, searchFilter, refresh, setUsers ]);
useEffect(() =>
{
@ -554,7 +555,7 @@ const Main = () =>
return errorToast(response.message);
setRoles(new Map(response.data.roles.map((role) => [ role.id, role ])));
})();
}, [ refresh ]);
}, [ refresh, setRoles ]);
return <Routes>
<Route path='/*' element={<UserList {...{ page, pages, setPage, loadState, onRefresh: () => setRefresh(val => !val) }} />} />
@ -569,7 +570,8 @@ const Users = () =>
useEffect(() =>
{
subtitle.set('Users');
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return <ErrorBoundary>
<UsersContext>
<Main/>