Skip to content

Commit

Permalink
feat: kysely project suggestion
Browse files Browse the repository at this point in the history
  • Loading branch information
asabotovich committed Jul 29, 2024
1 parent f1b553a commit b0dc889
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 91 deletions.
2 changes: 1 addition & 1 deletion src/components/GoalParentDropdown/GoalParentDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const GoalParentDropdown = ({
},
);

const { data: suggestionsProjects = [] } = trpc.project.suggestions.useQuery(
const { data: suggestionsProjects = [] } = trpc.v2.project.suggestions.useQuery(
{
query: inputState,
filter: filterIds,
Expand Down
1 change: 0 additions & 1 deletion src/schema/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export const projectDeepInfoSchema = queryWithFiltersSchema.extend({
export const projectSuggestionsSchema = z.object({
query: z.string(),
take: z.number().optional(),
include: z.array(z.string()).optional(),
filter: z.array(z.string()).optional(),
});

Expand Down
30 changes: 5 additions & 25 deletions src/utils/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,11 @@ export const filtersPanelSsrInit = async ({ query, ssrHelpers, req }: SSRProps)
: browserQueryState;

await Promise.all([
ssrHelpers.user.suggestions.fetch({
take: filtersTakeCount,
query: '',
include: queryState.owner,
}),
ssrHelpers.user.suggestions.fetch({
take: filtersTakeCount,
query: '',
include: queryState.participant,
}),
ssrHelpers.user.suggestions.fetch({
take: filtersTakeCount,
query: '',
include: queryState.issuer,
}),
ssrHelpers.project.suggestions.fetch({
take: filtersTakeCount,
query: '',
include: queryState.project,
}),
ssrHelpers.tag.suggestions.fetch({
take: filtersTakeCount,
query: '',
include: queryState.tag,
}),
ssrHelpers.user.getFilterUsersByIds.fetch(queryState.owner ?? []),
ssrHelpers.user.getFilterUsersByIds.fetch(queryState.participant ?? []),
ssrHelpers.user.getFilterUsersByIds.fetch(queryState.issuer ?? []),
ssrHelpers.project.getByIds.fetch({ ids: queryState.project ?? [] }),
ssrHelpers.tag.getByIds.fetch(queryState.tag ?? []),
ssrHelpers.state.all.fetch(),
]);

Expand Down
41 changes: 41 additions & 0 deletions trpc/queries/projectV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -553,3 +553,44 @@ export const getWholeGoalCountByProjectIds = (params: GetWholeGoalCountByProject
),
);
};

interface GetProjectSuggestionsParams {
activityId: string;
role: Role;
query: string;
filter?: string[];
limit?: number;
}

export const getProjectSuggestions = ({
role,
filter = [],
query,
limit = 5,
activityId,
}: GetProjectSuggestionsParams) => {
return db
.selectFrom('Project')
.selectAll()
.where('Project.archived', 'is not', true)
.where('Project.title', 'ilike', `%${query}%`)
.$if(role === Role.USER, (qb) =>
qb.where(({ or, eb, not, exists }) =>
or([
eb('Project.activityId', '=', activityId),
eb('Project.id', 'in', ({ selectFrom }) =>
selectFrom('_projectAccess').select('B').where('A', '=', activityId),
),
not(
exists(({ selectFrom }) =>
selectFrom('_projectAccess').select('B').whereRef('B', '=', 'Project.id'),
),
),
]),
),
)
.$if(filter.length > 0, (qb) => qb.where('Project.id', 'not in', filter))
.groupBy('Project.id')
.orderBy(sql`CHAR_LENGTH(title)`)
.limit(limit);
};
63 changes: 0 additions & 63 deletions trpc/router/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
projectCreateSchema,
projectTransferOwnershipSchema,
projectUpdateSchema,
projectSuggestionsSchema,
projectDeleteSchema,
participantsToProjectSchema,
teamsToProjectSchema,
Expand Down Expand Up @@ -65,68 +64,6 @@ const getUserItemsWhereSchema = ({ type, activityId }: { type: 'goal' | 'project
};

export const project = router({
suggestions: protectedProcedure
.input(projectSuggestionsSchema)
.query(async ({ input: { query, take = 5, include, filter }, ctx }) => {
const { activityId, role } = ctx.session.user;

const includeInput = {
activity: {
include: {
user: true,
},
},
flow: {
include: {
states: true,
},
},
};

// TODO: should we use getProjectSchema here?

const accessFilter = getProjectAccessFilter(activityId, role);
const requests = [
prisma.project.findMany({
take,
where: {
personal: false,
title: {
contains: query,
mode: 'insensitive',
},
...accessFilter,
...(include?.length || filter?.length
? {
id: {
notIn: [...(filter || []), ...(include || [])],
},
}
: {}),
...nonArchivedPartialQuery,
},
include: includeInput,
}),
];

if (include) {
requests.push(
prisma.project.findMany({
where: {
id: {
in: include,
},
personal: false,
...accessFilter,
...nonArchivedPartialQuery,
},
include: includeInput,
}),
);
}

return Promise.all(requests).then(([suggest, included = []]) => [...included, ...suggest]);
}),
getUserProjectsWithGoals: protectedProcedure
.input(
z.object({
Expand Down
26 changes: 25 additions & 1 deletion trpc/router/projectV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { sql } from 'kysely';
import { jsonBuildObject } from 'kysely/helpers/postgres';

import { router, protectedProcedure } from '../trpcBackend';
import { userProjectsSchema } from '../../src/schema/project';
import { projectSuggestionsSchema, userProjectsSchema } from '../../src/schema/project';
import {
getProjectsByIds,
getStarredProjectsIds,
getProjectSuggestions,
getUserProjectsQuery,
getUserProjectsWithGoals,
getWholeGoalCountByProjectIds,
Expand Down Expand Up @@ -57,6 +58,29 @@ interface ProjectsWithGoals extends Pick<ProjectResponse, 'id'> {
}

export const project = router({
suggestions: protectedProcedure
.input(projectSuggestionsSchema)
.query(async ({ input: { query, take = 5, filter }, ctx }) => {
const { activityId, role } = ctx.session.user;

try {
const sql = getProjectSuggestions({
role,
query,
filter,
limit: take,
activityId,
});

const res = await sql.execute();

return res;
} catch (error) {
console.error(error);

return Promise.reject(error);
}
}),
userProjects: protectedProcedure.input(userProjectsSchema).query(async ({ ctx, input: { take, filter } }) => {
const { activityId, role } = ctx.session.user;
try {
Expand Down

0 comments on commit b0dc889

Please sign in to comment.