Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: portal frontend 45 #55

Merged
merged 9 commits into from
Sep 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/api/endpoints/authFactor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,24 @@ import { type EndpointBuilder } from "@reduxjs/toolkit/query/react"
import {
buildUrl,
tagData,
type ListArg,
type ListResult,
type ListArg as _ListArg,
type ListResult as _ListResult,
} from "../../utils/api"
import type { AuthFactor } from "../models"
import { type TagTypes } from "../tagTypes"
import urls from "../urls"

export const AUTH_FACTOR_TAG: TagTypes = "AuthFactor"

export type ListAuthFactorsResult = ListResult<AuthFactor, "type">
export type ListAuthFactorsArg = ListArg
export type ListAuthFactorsResult = _ListResult<AuthFactor, "type">
export type ListAuthFactorsArg = _ListArg

export default function getReadAuthFactorEndpoints(
build: EndpointBuilder<any, any, any>,
) {
export default function getReadAuthFactorEndpoints<
ListResult extends _ListResult<AuthFactor> = ListAuthFactorsResult,
ListArg extends _ListArg<AuthFactor> = ListAuthFactorsArg,
>(build: EndpointBuilder<any, any, any>) {
return {
listAuthFactors: build.query<ListAuthFactorsResult, ListAuthFactorsArg>({
listAuthFactors: build.query<ListResult, ListArg>({
query: search => ({
url: buildUrl(urls.authFactor.list, { search }),
method: "GET",
Expand Down
77 changes: 52 additions & 25 deletions src/api/endpoints/klass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,49 +3,76 @@ import { type EndpointBuilder } from "@reduxjs/toolkit/query/react"
import {
buildUrl,
tagData,
type ListArg,
type ListResult,
type RetrieveArg,
type RetrieveResult,
type ListArg as _ListArg,
type ListResult as _ListResult,
type RetrieveArg as _RetrieveArg,
type RetrieveResult as _RetrieveResult,
} from "../../utils/api"
import type { Class, Teacher } from "../models"
import type {
Class,
Teacher,
SchoolTeacher,
SchoolTeacherUser,
} from "../models"
import { type TagTypes } from "../tagTypes"
import urls from "../urls"

export const CLASS_TAG: TagTypes = "Class"

export type RetrieveClassResult = RetrieveResult<
export type RetrieveClassResult = _RetrieveResult<
Class,
| "name"
| "read_classmates_data"
| "receive_requests_until"
| "school"
| "teacher"
>
export type RetrieveClassArg = RetrieveArg<Class>
"name" | "read_classmates_data" | "receive_requests_until" | "school"
> & {
teacher: SchoolTeacher & {
user: Pick<
SchoolTeacherUser,
| "id"
| "first_name"
| "last_name"
| "email"
| "is_active"
| "date_joined"
| "requesting_to_join_class"
>
}
}
export type RetrieveClassArg = _RetrieveArg<Class>

export type ListClassesResult = ListResult<
export type ListClassesResult = _ListResult<
Class,
| "name"
| "read_classmates_data"
| "receive_requests_until"
| "school"
| "teacher"
"name" | "read_classmates_data" | "receive_requests_until" | "school",
{
teacher: SchoolTeacher & {
user: Pick<
SchoolTeacherUser,
| "id"
| "first_name"
| "last_name"
| "email"
| "is_active"
| "date_joined"
| "requesting_to_join_class"
>
}
}
>
export type ListClassesArg = ListArg<{ teacher: Teacher["id"] }>
export type ListClassesArg = _ListArg<{ teacher: Teacher["id"] }>

export default function getReadClassEndpoints(
build: EndpointBuilder<any, any, any>,
) {
export default function getReadClassEndpoints<
RetrieveResult extends _RetrieveResult<Class> = RetrieveClassResult,
RetrieveArg extends _RetrieveArg<Class> = RetrieveClassArg,
ListResult extends _ListResult<Class> = ListClassesResult,
ListArg extends _ListArg<Class> = ListClassesArg,
>(build: EndpointBuilder<any, any, any>) {
return {
retrieveClass: build.query<RetrieveClassResult, RetrieveClassArg>({
retrieveClass: build.query<RetrieveResult, RetrieveArg>({
query: id => ({
url: buildUrl(urls.class.detail, { url: { id } }),
method: "GET",
}),
providesTags: tagData(CLASS_TAG),
}),
listClasses: build.query<ListClassesResult, ListClassesArg>({
listClasses: build.query<ListResult, ListArg>({
query: search => ({
url: buildUrl(urls.class.list, { search }),
method: "GET",
Expand Down
17 changes: 9 additions & 8 deletions src/api/endpoints/school.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,27 @@ import { type EndpointBuilder } from "@reduxjs/toolkit/query/react"
import {
buildUrl,
tagData,
type RetrieveArg,
type RetrieveResult,
type RetrieveArg as _RetrieveArg,
type RetrieveResult as _RetrieveResult,
} from "../../utils/api"
import type { School } from "../models"
import { type TagTypes } from "../tagTypes"
import urls from "../urls"

export const SCHOOL_TAG: TagTypes = "School"

export type RetrieveSchoolResult = RetrieveResult<
export type RetrieveSchoolResult = _RetrieveResult<
School,
"name" | "country" | "uk_county"
>
export type RetrieveSchoolArg = RetrieveArg<School>
export type RetrieveSchoolArg = _RetrieveArg<School>

export default function getReadSchoolEndpoints(
build: EndpointBuilder<any, any, any>,
) {
export default function getReadSchoolEndpoints<
RetrieveResult extends _RetrieveResult<School> = RetrieveSchoolResult,
RetrieveArg extends _RetrieveArg<School> = RetrieveSchoolArg,
>(build: EndpointBuilder<any, any, any>) {
return {
retrieveSchool: build.query<RetrieveSchoolResult, RetrieveSchoolArg>({
retrieveSchool: build.query<RetrieveResult, RetrieveArg>({
query: id => ({
url: buildUrl(urls.school.detail, { url: { id } }),
method: "GET",
Expand Down
31 changes: 17 additions & 14 deletions src/api/endpoints/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ import { type EndpointBuilder } from "@reduxjs/toolkit/query/react"
import {
buildUrl,
tagData,
type ListArg,
type ListResult,
type RetrieveArg,
type RetrieveResult,
type ListArg as _ListArg,
type ListResult as _ListResult,
type RetrieveArg as _RetrieveArg,
type RetrieveResult as _RetrieveResult,
} from "../../utils/api"
import type { Class, User } from "../models"
import { type TagTypes } from "../tagTypes"
import urls from "../urls"

export const USER_TAG: TagTypes = "User"

export type RetrieveUserResult = RetrieveResult<
export type RetrieveUserResult = _RetrieveResult<
User,
| "first_name"
| "last_name"
Expand All @@ -25,9 +25,9 @@ export type RetrieveUserResult = RetrieveResult<
| "student"
| "teacher"
>
export type RetrieveUserArg = RetrieveArg<User>
export type RetrieveUserArg = _RetrieveArg<User>

export type ListUsersResult = ListResult<
export type ListUsersResult = _ListResult<
User,
| "first_name"
| "last_name"
Expand All @@ -38,25 +38,28 @@ export type ListUsersResult = ListResult<
| "student"
| "teacher"
>
export type ListUsersArg = ListArg<{
export type ListUsersArg = _ListArg<{
students_in_class: Class["id"]
only_teachers: boolean
_id: User["id"] | User["id"][]
name: string
type: "teacher" | "student" | "independent" | "indy"
}>

export default function getReadUserEndpoints(
build: EndpointBuilder<any, any, any>,
) {
export default function getReadUserEndpoints<
RetrieveResult extends _RetrieveResult<User> = RetrieveUserResult,
RetrieveArg extends _RetrieveArg<User> = RetrieveUserArg,
ListResult extends _ListResult<User> = ListUsersResult,
ListArg extends _ListArg<User> = ListUsersArg,
>(build: EndpointBuilder<any, any, any>) {
return {
retrieveUser: build.query<RetrieveUserResult, RetrieveUserArg>({
retrieveUser: build.query<RetrieveResult, RetrieveArg>({
query: id => ({
url: buildUrl(urls.user.detail, { url: { id } }),
method: "GET",
}),
providesTags: tagData(USER_TAG),
}),
listUsers: build.query<ListUsersResult, ListUsersArg>({
listUsers: build.query<ListResult, ListArg>({
query: search => ({
url: buildUrl(urls.user.list, { search }),
method: "GET",
Expand Down
34 changes: 18 additions & 16 deletions src/api/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,36 +23,40 @@ export type User = Model<
>

export type TeacherUser<Fields = User> = Fields & {
email: string
last_name: string
teacher: Teacher
student: undefined
}

export type SchoolTeacherUser<Fields = User> = Fields & {
export type SchoolTeacherUser<Fields = User> = TeacherUser<Fields> & {
teacher: SchoolTeacher
student: undefined
}

export type AdminSchoolTeacherUser<Fields = User> = Fields & {
teacher: AdminSchoolTeacher
student: undefined
}
export type AdminSchoolTeacherUser<Fields = User> =
SchoolTeacherUser<Fields> & {
teacher: AdminSchoolTeacher
}

export type NonAdminSchoolTeacherUser<Fields = User> = Fields & {
teacher: NonAdminSchoolTeacher
student: undefined
}
export type NonAdminSchoolTeacherUser<Fields = User> =
SchoolTeacherUser<Fields> & {
teacher: NonAdminSchoolTeacher
}

export type NonSchoolTeacherUser<Fields = User> = Fields & {
export type NonSchoolTeacherUser<Fields = User> = TeacherUser<Fields> & {
teacher: NonSchoolTeacher
student: undefined
}

export type StudentUser<Fields = User> = Fields & {
email: undefined
last_name: undefined
teacher: undefined
student: Student
}

export type IndependentUser<Fields = User> = Fields & {
email: string
last_name: string
teacher: undefined
student: undefined
}
Expand All @@ -74,13 +78,11 @@ export type SchoolTeacher<Fields = Teacher> = Fields & {
school: number
}

export type AdminSchoolTeacher<Fields = Teacher> = Fields & {
school: number
export type AdminSchoolTeacher<Fields = Teacher> = SchoolTeacher<Fields> & {
is_admin: true
}

export type NonAdminSchoolTeacher<Fields = Teacher> = Fields & {
school: number
export type NonAdminSchoolTeacher<Fields = Teacher> = SchoolTeacher<Fields> & {
is_admin: false
}

Expand Down
10 changes: 7 additions & 3 deletions src/components/TablePagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,13 @@ const TablePagination = <
limit: initialLimit,
})

useEffect(() => {
trigger({ limit, offset, ...filters } as QueryArg, preferCacheValue)
}, [trigger, limit, offset, filters, preferCacheValue])
useEffect(
() => {
trigger({ limit, offset, ...filters } as QueryArg, preferCacheValue)
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[trigger, limit, offset, ...Object.values(filters || {}), preferCacheValue],
)

const { count, max_limit } = result.data || {}

Expand Down
48 changes: 30 additions & 18 deletions src/components/form/ApiAutocompleteField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,27 +85,39 @@ const ApiAutocompleteField = <
}>({ options: {}, hasMore: true })

// Call api
useEffect(() => {
const arg = { limit, offset, ...filterOptions } as QueryArg
// @ts-expect-error
if (search) arg[searchKey] = search
useEffect(
() => {
const arg = { limit, offset, ...filterOptions } as QueryArg
// @ts-expect-error
if (search) arg[searchKey] = search

trigger(arg)
.unwrap()
.then(({ data, offset, limit, count }) => {
setState(({ options: previousOptions }) => {
const options = { ...previousOptions }
data.forEach(result => {
options[getOptionKey(result)] = result
trigger(arg, true)
.unwrap()
.then(({ data, offset, limit, count }) => {
setState(({ options: previousOptions }) => {
const options = { ...previousOptions }
data.forEach(result => {
options[getOptionKey(result)] = result
})
return { options, hasMore: offset + limit < count }
})
return { options, hasMore: offset + limit < count }
})
})
.catch(error => {
if (error) console.error(error)
// TODO: gracefully handle error
})
}, [trigger, limit, offset, filterOptions, getOptionKey, searchKey, search])
.catch(error => {
if (error) console.error(error)
// TODO: gracefully handle error
})
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[
trigger,
limit,
offset,
searchKey,
search,
// eslint-disable-next-line react-hooks/exhaustive-deps
...Object.values(filterOptions || {}),
],
)

// Get options keys
let optionKeys: ModelId[] = Object.keys(options)
Expand Down