diff --git a/src/core/server/graph/tenant/resolvers/comment.ts b/src/core/server/graph/tenant/resolvers/comment.ts index 9272a294c..d93612354 100644 --- a/src/core/server/graph/tenant/resolvers/comment.ts +++ b/src/core/server/graph/tenant/resolvers/comment.ts @@ -4,6 +4,7 @@ import { GQLCommentTypeResolver, } from "talk-server/graph/tenant/schema/__generated__/types"; import { Comment } from "talk-server/models/comment"; +import { createConnection } from "talk-server/models/connection"; const Comment: GQLCommentTypeResolver = { editing: (comment, input, ctx) => ({ @@ -20,10 +21,14 @@ const Comment: GQLCommentTypeResolver = { author: (comment, input, ctx) => ctx.loaders.Users.user.load(comment.author_id), replies: (comment, input, ctx) => - ctx.loaders.Comments.forParent(comment.asset_id, comment.id, input), + comment.reply_count > 0 + ? ctx.loaders.Comments.forParent(comment.asset_id, comment.id, input) + : createConnection(), parentCount: comment => comment.parent_id ? comment.grandparent_ids.length + 1 : 0, - replyCount: comment => comment.child_ids.length, + depth: comment => + comment.parent_id ? comment.grandparent_ids.length + 1 : 0, + replyCount: comment => comment.reply_count, rootParent: (comment, input, ctx, info) => { // If there isn't a parent, then return nothing! if (!comment.parent_id) { @@ -69,7 +74,10 @@ const Comment: GQLCommentTypeResolver = { return ctx.loaders.Comments.comment.load(comment.parent_id); }, parents: (comment, input, ctx) => - ctx.loaders.Comments.parents(comment, input), + // Some resolver optimization. + comment.parent_id + ? ctx.loaders.Comments.parents(comment, input) + : createConnection(), }; export default Comment; diff --git a/src/core/server/graph/tenant/schema/schema.graphql b/src/core/server/graph/tenant/schema/schema.graphql index 142d59973..fdc17718c 100644 --- a/src/core/server/graph/tenant/schema/schema.graphql +++ b/src/core/server/graph/tenant/schema/schema.graphql @@ -641,15 +641,21 @@ type Comment { status: COMMENT_STATUS! """ - parentCount is the number of direct parents for this Comment. + parentCount is the number of direct parents for this Comment. Currently this + value is the same as depth. """ - parentCount: Int + parentCount: Int! + + """ + depth is the number of levels that a given comment is deep. + """ + depth: Int! """ replyCount is the number of replies. Only direct replies to this Comment are counted. Deleted comments are included in this count. """ - replyCount: Int + replyCount: Int! """ replies will return the replies to this Comment. @@ -658,7 +664,7 @@ type Comment { first: Int = 10 orderBy: COMMENT_SORT = CREATED_AT_DESC after: Cursor - ): CommentsConnection + ): CommentsConnection! """ parent is the immediate parent of a given comment. @@ -675,7 +681,7 @@ type Comment { parents returns a CommentsConnection that allows accessing direct parents of the given Comment. """ - parents(last: Int = 1, before: Cursor): CommentsConnection + parents(last: Int = 1, before: Cursor): CommentsConnection! """ editing returns details about the edit status of a Comment. @@ -835,11 +841,6 @@ type Query { """ comment(id: ID!): Comment - """ - assets returns a AssetsConnection. - """ - assets(cursor: Cursor, limit: Int = 10): AssetsConnection - """ asset is the Asset specified by its ID/URL. """ diff --git a/src/core/server/models/comment.ts b/src/core/server/models/comment.ts index 3e2b06cb4..a780b24ad 100644 --- a/src/core/server/models/comment.ts +++ b/src/core/server/models/comment.ts @@ -10,6 +10,7 @@ import { import { ActionCounts } from "talk-server/models/actions"; import { Connection, + createConnection, Cursor, getPageInfo, nodesToEdges, @@ -28,7 +29,7 @@ export interface BodyHistoryItem { } export interface StatusHistoryItem { - status: GQLCOMMENT_STATUS; // TODO: migrate field + status: GQLCOMMENT_STATUS; assigned_by?: string; created_at: Date; } @@ -44,7 +45,8 @@ export interface Comment extends TenantResource { status_history: StatusHistoryItem[]; action_counts: ActionCounts; grandparent_ids: string[]; - child_ids: string[]; + reply_ids: string[]; + reply_count: number; created_at: Date; deleted_at?: Date; metadata?: Record; @@ -55,8 +57,8 @@ export type CreateCommentInput = Omit< | "id" | "tenant_id" | "created_at" - // child_ids are always empty for a new comment. - | "child_ids" + | "reply_ids" + | "reply_count" | "body_history" | "status_history" >; @@ -77,7 +79,8 @@ export async function createComment( id: uuid.v4(), tenant_id: tenantID, created_at: now, - child_ids: [], + reply_ids: [], + reply_count: 0, body_history: [ { body, @@ -121,9 +124,8 @@ export async function pushChildCommentIDOntoParent( id: parentID, }, { - $push: { - child_ids: childID, - }, + $push: { reply_ids: childID }, + $inc: { reply_count: 1 }, } ); @@ -318,25 +320,23 @@ export async function retrieveCommentParentsConnection( ): Promise>>> { // Return nothing if this comment does not have any parents. if (!comment.parent_id) { - return { - edges: [], + return createConnection({ pageInfo: { hasNextPage: false, hasPreviousPage: false, }, - }; + }); } // TODO: (wyattjoh) maybe throw an error when the limit is zero? if (limit <= 0) { - return { - edges: [], + return createConnection({ pageInfo: { hasNextPage: false, hasPreviousPage: false, }, - }; + }); } // If the last paramter is 1, and the after paramter is either unset or equal diff --git a/src/core/server/models/connection.ts b/src/core/server/models/connection.ts index e45e9657a..3eeacd937 100644 --- a/src/core/server/models/connection.ts +++ b/src/core/server/models/connection.ts @@ -1,3 +1,5 @@ +import { merge } from "lodash"; + export type Cursor = Date | number | string | null; export interface Edge { @@ -17,6 +19,25 @@ export interface Connection { pageInfo: PageInfo; } +/** + * createConnection will create a base Connection that can be used to satisfy + * the Connection interface. + * + * @param connection the base connection to optionally merge with the default base + * connection details. + */ +export function createConnection( + connection: Partial> = {} +): Connection { + return merge( + { + edges: [], + pageInfo: {}, + }, + connection + ); +} + export interface PaginationArgs { first: number; }