Files
speckle-server/packages/server/modules/workspaces/services/retrieval.ts
T
Chuck Driesler bbd5146e5a fix(workspaces): add pagination to workspace team members (#2644)
* fix(workspaces): a suggestion of paginated teams

* fix(workspaces): workspace team pagination (?)

* fix(workspaces): pagination based on acl createdAt

* fix(workspaces): fix some roles-related tests

* fix(workspaces): improve query and tests

* fix(workspaces): collaborators query without incorrect groupBy

* fix(workspaces): add default values to migration

* Fixed queries and fragments

* Merged main

* Remove comment

* chore(workspaces): update WorkspaceCollaboratorCollection mocks

* chore(workspaces): fix role test

* chore(workspaces); ope

* fix(workspaces): move workspace acl timestamps to separate table

* Merge?

* fix(workspaces) drop that table

* fix(workspaces): cursor

* fix(workspaceInvites): undo merge borkage

* fix(workspaces): rework workspace member pagination

* fix(workspaces): fix test

* fix(workspaces): test test

* fix(workspaces): literally garbage

---------

Co-authored-by: Mike Tasset <mike.tasset@gmail.com>
Co-authored-by: Gergő Jedlicska <gergo@jedlicska.com>
2024-08-29 21:17:37 +02:00

113 lines
3.2 KiB
TypeScript

import { FindEmailsByUserId } from '@/modules/core/domain/userEmails/operations'
import {
decodeIsoDateCursor,
encodeIsoDateCursor
} from '@/modules/shared/helpers/graphqlHelper'
import {
GetUserDiscoverableWorkspaces,
GetWorkspace,
GetWorkspaceCollaborators,
GetWorkspaceCollaboratorsArgs,
GetWorkspaceCollaboratorsTotalCount,
GetWorkspaceRolesForUser
} from '@/modules/workspaces/domain/operations'
import { WorkspaceTeam } from '@/modules/workspaces/domain/types'
import { Workspace } from '@/modules/workspacesCore/domain/types'
import { chunk, isNull } from 'lodash'
type GetDiscoverableWorkspaceForUserArgs = {
userId: string
}
export const getDiscoverableWorkspacesForUserFactory =
({
findEmailsByUserId,
getDiscoverableWorkspaces
}: {
findEmailsByUserId: FindEmailsByUserId
getDiscoverableWorkspaces: GetUserDiscoverableWorkspaces
}) =>
async ({
userId
}: GetDiscoverableWorkspaceForUserArgs): Promise<
Pick<Workspace, 'id' | 'name' | 'description' | 'logo' | 'defaultLogoIndex'>[]
> => {
const userEmails = await findEmailsByUserId({ userId })
const userVerifiedDomains = userEmails
.filter((email) => email.verified)
.map((email) => email.email.split('@')[1])
const workspaces = await getDiscoverableWorkspaces({
domains: userVerifiedDomains,
userId
})
return workspaces
}
type GetWorkspacesForUserArgs = {
userId: string
}
export const getWorkspacesForUserFactory =
({
getWorkspace,
getWorkspaceRolesForUser
}: {
getWorkspace: GetWorkspace
getWorkspaceRolesForUser: GetWorkspaceRolesForUser
}) =>
async ({ userId }: GetWorkspacesForUserArgs): Promise<Workspace[]> => {
const workspaceRoles = await getWorkspaceRolesForUser({ userId })
const workspaces: Workspace[] = []
for (const workspaceRoleBatch of chunk(workspaceRoles, 20)) {
// TODO: Use `getWorkspaces`, which I saw Fabians already wrote in another PR
const workspacesBatch = await Promise.all(
workspaceRoleBatch.map(({ workspaceId }) => getWorkspace({ workspaceId }))
)
workspaces.push(
...workspacesBatch.filter(
(workspace): workspace is Workspace => !isNull(workspace)
)
)
}
return workspaces
}
type WorkspaceTeamCollection = {
items: WorkspaceTeam
cursor: string | null
totalCount: number
}
export const getPaginatedWorkspaceTeamFactory =
({
getWorkspaceCollaborators,
getWorkspaceCollaboratorsTotalCount
}: {
getWorkspaceCollaborators: GetWorkspaceCollaborators
getWorkspaceCollaboratorsTotalCount: GetWorkspaceCollaboratorsTotalCount
}) =>
async (args: GetWorkspaceCollaboratorsArgs): Promise<WorkspaceTeamCollection> => {
const maybeDecodedCursor = args.cursor ? decodeIsoDateCursor(args.cursor) : null
const items = await getWorkspaceCollaborators({
...args,
cursor: maybeDecodedCursor ?? undefined
})
const totalCount = await getWorkspaceCollaboratorsTotalCount(args)
let cursor = null
if (items.length === args.limit) {
const lastItem = items.at(-1)
cursor = lastItem ? encodeIsoDateCursor(lastItem.createdAt) : null
}
return {
items,
cursor,
totalCount
}
}