Skip to content

Commit

Permalink
Feat: user search returns partial results (#1161)
Browse files Browse the repository at this point in the history
* feat: use sub for user search; return results from different fields

* add some more meta information on user search
  • Loading branch information
mipyykko committed Apr 12, 2023
1 parent 2cba213 commit 162954d
Show file tree
Hide file tree
Showing 22 changed files with 999 additions and 225 deletions.
4 changes: 3 additions & 1 deletion backend/graphql/Completion/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ export const CompletionQueries = extendType({
completion_language,
...(search
? {
user: buildUserSearch(search),
user: {
OR: buildUserSearch(search),
},
}
: {}),
},
Expand Down
105 changes: 101 additions & 4 deletions backend/graphql/User/queries.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { extendType, idArg, intArg, stringArg } from "nexus"
import {
extendType,
idArg,
intArg,
nonNull,
objectType,
stringArg,
} from "nexus"

import { User } from "@prisma/client"

import { isAdmin } from "../../accessControl"
import { ForbiddenError, UserInputError } from "../../lib/errors"
import { buildUserSearch, convertPagination } from "../../util/db-functions"
import { notEmpty } from "../../util/notEmpty"

export const UserQueries = extendType({
type: "Query",
Expand Down Expand Up @@ -30,7 +40,7 @@ export const UserQueries = extendType({
resolve: async (_, { id, search, upstream_id }, ctx) => {
const user = await ctx.prisma.user.findFirst({
where: {
...buildUserSearch(search),
...(search ? { OR: buildUserSearch(search) } : {}),
id: id ?? undefined,
upstream_id: upstream_id ?? undefined,
},
Expand Down Expand Up @@ -60,7 +70,9 @@ export const UserQueries = extendType({

return ctx.prisma.user.findMany({
...convertPagination({ first, last, before, after, skip }),
where: buildUserSearch(search),
where: {
OR: buildUserSearch(search),
},
})
},
extendConnection(t) {
Expand All @@ -70,7 +82,9 @@ export const UserQueries = extendType({
},
resolve: async (_, { search }, ctx) => {
return ctx.prisma.user.count({
where: buildUserSearch(search),
where: {
OR: buildUserSearch(search),
},
})
},
})
Expand All @@ -88,3 +102,86 @@ export const UserQueries = extendType({
})
},
})

export const UserSearch = objectType({
name: "UserSearch",
definition(t) {
t.string("search")
t.string("field", { description: "current search condition field(s)" })
t.string("fieldValue", {
description: "values used for current search condition field(s)",
})
t.nonNull.list.nonNull.field("matches", { type: "User" })
t.nonNull.int("count", { description: "total count of matches so far" })
t.nonNull.int("fieldIndex", {
description: "index of current search field",
})
t.nonNull.int("fieldCount", {
description: "total number of search fields",
})
t.nonNull.int("fieldResultCount", {
description: "total number of matches for current search field",
})
t.nonNull.int("fieldUniqueResultCount", {
description: "total number of unique matches for current search field",
})
t.nonNull.boolean("finished")
},
})

export const UserSubscriptions = extendType({
type: "Subscription",
definition(t) {
t.nonNull.field("userSearch", {
type: "UserSearch",
args: {
search: nonNull(stringArg()),
},
// authorize: isAdmin,
subscribe(_, { search }, ctx) {
const queries = buildUserSearch(search) ?? []
const fieldCount = queries.length
let users: Array<User> = []

return (async function* () {
let fieldIndex = 1
for (const query of queries) {
const field = Object.keys(query).join(", ")
const fieldValue = Object.values(query)
.map((q) =>
q !== null && typeof q === "object" && "contains" in q
? q.contains
: q,
)
.filter(notEmpty)
.join(", ")
const res = await ctx.prisma.user.findMany({
where: query,
})
const newUsers = res.filter(
(u) => !users.find((u2) => u2.id === u.id),
)
users = users.concat(newUsers)

yield {
field,
fieldValue,
search,
count: users.length,
fieldIndex,
fieldCount,
fieldResultCount: res.length,
fieldUniqueResultCount: newUsers.length,
matches: newUsers,
finished: fieldIndex === fieldCount,
}
fieldIndex++
}
})()
},
resolve(eventData) {
return eventData
},
})
},
})
3 changes: 2 additions & 1 deletion backend/graphql/UserCourseSetting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,8 @@ const getUserCourseSettingSearch = ({
user_id,
user_upstream_id,
}: GetUserCourseSettingSearchArgs) => {
const userSearch = search && search !== "" ? buildUserSearch(search) : null
const userSearch =
search && search !== "" ? { OR: buildUserSearch(search) } : null

const userConditions = [
user_id || user_upstream_id
Expand Down
Loading

0 comments on commit 162954d

Please sign in to comment.