Loading frontend/src/pages/(navbar)/users/index.tsx +6 −2 Original line number Diff line number Diff line import LinkButton from '@/components/LinkButton' import type { Section } from '@/components/Sidebar' import Sidebar from '@/components/Sidebar' import Table from '@/components/Table' import { useNavigate } from '@/router' import UserCreator from '@/users/UserCreator' import Active from '@/users/UserTable/Filters/Active' Loading @@ -17,6 +18,7 @@ import { sidebarClass } from '@/views/classes' import { Button, InputGroup, Navbar } from '@blueprintjs/core' import { css } from '@emotion/css' import Reloader from '@inject/graphql/components/Reloader' import type { User } from '@inject/graphql/fragment-types' import { ReloadTable } from '@inject/graphql/mutations.client' import { useState } from 'react' import { useClient } from 'urql' Loading Loading @@ -50,7 +52,7 @@ const Page = () => { }) const [tags, setTags] = useState<string[]>([]) const [columns, setColumns] = useState<UserColumn[]>(USER_COLUMNS) const { table } = useUserTable({ const tableProps = useUserTable({ onClick: (userId: string) => nav('/users/:userId', { params: { userId } }), groups, active, Loading Loading @@ -122,7 +124,9 @@ const Page = () => { return ( <div className={page}> <div className={body}>{table}</div> <div className={body}> <Table<User> {...tableProps} /> </div> {element} <Sidebar position='right' className={sidebarClass} sections={sections} /> </div> Loading frontend/src/users/ExerciseAssignment/AssignByTags.tsx +4 −4 Original line number Diff line number Diff line import Table from '@/components/Table' import { Button, Dialog, Loading @@ -7,6 +8,7 @@ import { InputGroup, } from '@blueprintjs/core' import { css, cx } from '@emotion/css' import type { User } from '@inject/graphql/fragment-types' import { useTypedMutation } from '@inject/graphql/graphql' import { AssignUsersByTags } from '@inject/graphql/mutations' import { dialogBody, maximizedDialog } from '@inject/shared/css/dialog' Loading Loading @@ -48,10 +50,8 @@ const AssignByTags: FC<AssignByTagsProps> = ({ exerciseId }) => { }).then(() => reset()) }, [assignByTags, exerciseId, reset, selectedUsers, tagPrefix]) const { table } = useUserTableSelection({ const tableProps = useUserTableSelection({ groups: AUTH_GROUPS, onCancel: reset, onAdd: (ids: string[]) => setSelectedUsers(ids), selectedUsers, setSelectedUsers, /* Loading Loading @@ -95,7 +95,7 @@ const AssignByTags: FC<AssignByTagsProps> = ({ exerciseId }) => { onChange={e => setTagPrefix(e.target.value)} /> </FormGroup> {table} <Table<User> {...tableProps} /> </DialogBody> <DialogFooter actions={ Loading frontend/src/users/ExerciseAssignment/AssignEqually.tsx +6 −4 Original line number Diff line number Diff line import Table from '@/components/Table' import { Alert, Button, Loading @@ -6,6 +7,7 @@ import { DialogFooter, } from '@blueprintjs/core' import { css, cx } from '@emotion/css' import type { User } from '@inject/graphql/fragment-types' import { useTypedMutation } from '@inject/graphql/graphql' import { AssignUsersEqually } from '@inject/graphql/mutations' import { dialogBody, maximizedDialog } from '@inject/shared/css/dialog' Loading Loading @@ -53,10 +55,8 @@ const AssignEqually: FC<AssignEquallyProps> = ({ exerciseId, teamCount }) => { }).then(() => reset()) }, [assignEqually, exerciseId, reset, selectedUsers, teamCount, warningOpen]) const { table } = useUserTableSelection({ const tableProps = useUserTableSelection({ groups: AUTH_GROUPS, onCancel: reset, onAdd: (ids: string[]) => setSelectedUsers(ids), selectedUsers, setSelectedUsers, }) Loading @@ -77,7 +77,9 @@ const AssignEqually: FC<AssignEquallyProps> = ({ exerciseId, teamCount }) => { title='Assign users to teams equally' icon='align-justify' > <DialogBody className={cx(dialogBody, body)}>{table}</DialogBody> <DialogBody className={cx(dialogBody, body)}> <Table<User> {...tableProps} /> </DialogBody> <DialogFooter actions={ <Button Loading frontend/src/users/useDeleteUsers.tsx→frontend/src/users/RemoveUsers.tsx +85 −0 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import { useTypedMutation } from '@inject/graphql/graphql' import { DeleteUsers } from '@inject/graphql/mutations' import { useMemo, useState } from 'react' const useDeleteUsers = ({ const RemoveUsers = ({ userIds, showCount, onConfirm, Loading Loading @@ -34,7 +34,12 @@ const useDeleteUsers = ({ [id, userIds] ) const SuperUserButton = () => ( if (!isSuperuser) { return null } return ( <> <Button disabled={disabled} title={title} Loading @@ -45,9 +50,6 @@ const useDeleteUsers = ({ > {`Delete${showCount ? ` (${userCount})` : ''}`} </Button> ) const SuperUserAlert = () => ( <Alert loading={loading} isOpen={alertOpen} Loading Loading @@ -76,12 +78,8 @@ const useDeleteUsers = ({ <p>The current user will not be deleted.</p> )} </Alert> </> ) return { button: isSuperuser ? <SuperUserButton /> : undefined, alert: isSuperuser ? <SuperUserAlert /> : undefined, } } export default useDeleteUsers export default RemoveUsers frontend/src/users/useResetCredentials.tsx→frontend/src/users/ResetCredentials.tsx +10 −8 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import { useTypedMutation } from '@inject/graphql/graphql' import { RegenerateCredentials } from '@inject/graphql/mutations' import { useMemo, useState } from 'react' const useRegenerateCredentials = ({ userIds }: { userIds: string[] }) => { const ResetCredentials = ({ userIds }: { userIds: string[] }) => { const [alertOpen, setAlertOpen] = useState(false) const { id, isSuperuser } = useAuthIdentity() const [{ fetching: loading }, mutate] = useTypedMutation( Loading @@ -19,8 +19,12 @@ const useRegenerateCredentials = ({ userIds }: { userIds: string[] }) => { return { disabled: false, title: undefined } }, [userIds]) return { button: isSuperuser && ( if (!isSuperuser) { return null } return ( <> <Button disabled={disabled} title={title} Loading @@ -33,8 +37,6 @@ const useRegenerateCredentials = ({ userIds }: { userIds: string[] }) => { > {`Reset credentials${userIds.length > 1 ? ` for selected` : ''}`} </Button> ), alert: isSuperuser && ( <Alert loading={loading} isOpen={alertOpen} Loading Loading @@ -77,8 +79,8 @@ const useRegenerateCredentials = ({ userIds }: { userIds: string[] }) => { </p> )} </Alert> ), } </> ) } export default useRegenerateCredentials export default ResetCredentials Loading
frontend/src/pages/(navbar)/users/index.tsx +6 −2 Original line number Diff line number Diff line import LinkButton from '@/components/LinkButton' import type { Section } from '@/components/Sidebar' import Sidebar from '@/components/Sidebar' import Table from '@/components/Table' import { useNavigate } from '@/router' import UserCreator from '@/users/UserCreator' import Active from '@/users/UserTable/Filters/Active' Loading @@ -17,6 +18,7 @@ import { sidebarClass } from '@/views/classes' import { Button, InputGroup, Navbar } from '@blueprintjs/core' import { css } from '@emotion/css' import Reloader from '@inject/graphql/components/Reloader' import type { User } from '@inject/graphql/fragment-types' import { ReloadTable } from '@inject/graphql/mutations.client' import { useState } from 'react' import { useClient } from 'urql' Loading Loading @@ -50,7 +52,7 @@ const Page = () => { }) const [tags, setTags] = useState<string[]>([]) const [columns, setColumns] = useState<UserColumn[]>(USER_COLUMNS) const { table } = useUserTable({ const tableProps = useUserTable({ onClick: (userId: string) => nav('/users/:userId', { params: { userId } }), groups, active, Loading Loading @@ -122,7 +124,9 @@ const Page = () => { return ( <div className={page}> <div className={body}>{table}</div> <div className={body}> <Table<User> {...tableProps} /> </div> {element} <Sidebar position='right' className={sidebarClass} sections={sections} /> </div> Loading
frontend/src/users/ExerciseAssignment/AssignByTags.tsx +4 −4 Original line number Diff line number Diff line import Table from '@/components/Table' import { Button, Dialog, Loading @@ -7,6 +8,7 @@ import { InputGroup, } from '@blueprintjs/core' import { css, cx } from '@emotion/css' import type { User } from '@inject/graphql/fragment-types' import { useTypedMutation } from '@inject/graphql/graphql' import { AssignUsersByTags } from '@inject/graphql/mutations' import { dialogBody, maximizedDialog } from '@inject/shared/css/dialog' Loading Loading @@ -48,10 +50,8 @@ const AssignByTags: FC<AssignByTagsProps> = ({ exerciseId }) => { }).then(() => reset()) }, [assignByTags, exerciseId, reset, selectedUsers, tagPrefix]) const { table } = useUserTableSelection({ const tableProps = useUserTableSelection({ groups: AUTH_GROUPS, onCancel: reset, onAdd: (ids: string[]) => setSelectedUsers(ids), selectedUsers, setSelectedUsers, /* Loading Loading @@ -95,7 +95,7 @@ const AssignByTags: FC<AssignByTagsProps> = ({ exerciseId }) => { onChange={e => setTagPrefix(e.target.value)} /> </FormGroup> {table} <Table<User> {...tableProps} /> </DialogBody> <DialogFooter actions={ Loading
frontend/src/users/ExerciseAssignment/AssignEqually.tsx +6 −4 Original line number Diff line number Diff line import Table from '@/components/Table' import { Alert, Button, Loading @@ -6,6 +7,7 @@ import { DialogFooter, } from '@blueprintjs/core' import { css, cx } from '@emotion/css' import type { User } from '@inject/graphql/fragment-types' import { useTypedMutation } from '@inject/graphql/graphql' import { AssignUsersEqually } from '@inject/graphql/mutations' import { dialogBody, maximizedDialog } from '@inject/shared/css/dialog' Loading Loading @@ -53,10 +55,8 @@ const AssignEqually: FC<AssignEquallyProps> = ({ exerciseId, teamCount }) => { }).then(() => reset()) }, [assignEqually, exerciseId, reset, selectedUsers, teamCount, warningOpen]) const { table } = useUserTableSelection({ const tableProps = useUserTableSelection({ groups: AUTH_GROUPS, onCancel: reset, onAdd: (ids: string[]) => setSelectedUsers(ids), selectedUsers, setSelectedUsers, }) Loading @@ -77,7 +77,9 @@ const AssignEqually: FC<AssignEquallyProps> = ({ exerciseId, teamCount }) => { title='Assign users to teams equally' icon='align-justify' > <DialogBody className={cx(dialogBody, body)}>{table}</DialogBody> <DialogBody className={cx(dialogBody, body)}> <Table<User> {...tableProps} /> </DialogBody> <DialogFooter actions={ <Button Loading
frontend/src/users/useDeleteUsers.tsx→frontend/src/users/RemoveUsers.tsx +85 −0 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import { useTypedMutation } from '@inject/graphql/graphql' import { DeleteUsers } from '@inject/graphql/mutations' import { useMemo, useState } from 'react' const useDeleteUsers = ({ const RemoveUsers = ({ userIds, showCount, onConfirm, Loading Loading @@ -34,7 +34,12 @@ const useDeleteUsers = ({ [id, userIds] ) const SuperUserButton = () => ( if (!isSuperuser) { return null } return ( <> <Button disabled={disabled} title={title} Loading @@ -45,9 +50,6 @@ const useDeleteUsers = ({ > {`Delete${showCount ? ` (${userCount})` : ''}`} </Button> ) const SuperUserAlert = () => ( <Alert loading={loading} isOpen={alertOpen} Loading Loading @@ -76,12 +78,8 @@ const useDeleteUsers = ({ <p>The current user will not be deleted.</p> )} </Alert> </> ) return { button: isSuperuser ? <SuperUserButton /> : undefined, alert: isSuperuser ? <SuperUserAlert /> : undefined, } } export default useDeleteUsers export default RemoveUsers
frontend/src/users/useResetCredentials.tsx→frontend/src/users/ResetCredentials.tsx +10 −8 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ import { useTypedMutation } from '@inject/graphql/graphql' import { RegenerateCredentials } from '@inject/graphql/mutations' import { useMemo, useState } from 'react' const useRegenerateCredentials = ({ userIds }: { userIds: string[] }) => { const ResetCredentials = ({ userIds }: { userIds: string[] }) => { const [alertOpen, setAlertOpen] = useState(false) const { id, isSuperuser } = useAuthIdentity() const [{ fetching: loading }, mutate] = useTypedMutation( Loading @@ -19,8 +19,12 @@ const useRegenerateCredentials = ({ userIds }: { userIds: string[] }) => { return { disabled: false, title: undefined } }, [userIds]) return { button: isSuperuser && ( if (!isSuperuser) { return null } return ( <> <Button disabled={disabled} title={title} Loading @@ -33,8 +37,6 @@ const useRegenerateCredentials = ({ userIds }: { userIds: string[] }) => { > {`Reset credentials${userIds.length > 1 ? ` for selected` : ''}`} </Button> ), alert: isSuperuser && ( <Alert loading={loading} isOpen={alertOpen} Loading Loading @@ -77,8 +79,8 @@ const useRegenerateCredentials = ({ userIds }: { userIds: string[] }) => { </p> )} </Alert> ), } </> ) } export default useRegenerateCredentials export default ResetCredentials