VirtusLab-Open-Source / strapi-plugin-comments

A plugin for Strapi Headless CMS that provides end to end comments feature with their moderation panel, bad words filtering, abuse reporting and more.
MIT License
413 stars 65 forks source link

How to get all comments (any relation) by a user with GraphQL? #209

Closed jnovak-SM2Dev closed 1 year ago

jnovak-SM2Dev commented 1 year ago

I'm trying to get all the comments by a user to show on their profile page, but the GraphQL findAllFlat and findAllInHierarchy calls require a relation. Is there a way to do this or does anyone know the best way to override the calls to make the relation optional so I can use the author filter only?

cyp3rius commented 1 year ago

Hello @SM2DevLLC, that seems as a feature request.

I'll schedule development for this.

jnovak-SM2Dev commented 1 year ago

@cyp3rius Sounds good. Thanks! I'm surprised no one else has wanted to show a users comments on a profile page or something like that before.

jnovak-SM2Dev commented 1 year ago

@cyp3rius I found a workaround for now. I'll leave this here in case it helps anyone else.

This goes in the index.ts (might be index.js if you aren't using typescript). This adds a query called findAllFlatAuthor where you don't need to pass in the related string, but instead pass in an authorId. I added more code to mine that also lets you get the related object as a response (which seems to be missing from this plugin as well).

export default {
  register({ strapi }) {
    const extensionService = strapi.plugin("graphql").service("extension");
    extensionService.use(({ strapi }) => ({
      typeDefs: `
    type Query {
      findAllFlatAuthor(authorId: String!, pagination: PaginationArg = {}, sort: [String] = []): ResponseFindAll
    }
  `,
      resolvers: {
        Query: {
          findAllFlatAuthor: {
            resolve: async (parent, args, context) => {
              const { toEntityCollectionResponse } = strapi.service(
                "plugin::graphql.format"
              ).returnTypes;

              const data = await strapi.services[
                "plugin::comments.common"
              ].findAllFlat({
                query: {
                  authorId: args.authorId,
                },
                pagination: args.pagination
                  ? {
                    ...args.pagination,
                    withCount: true,
                  }
                  : undefined,
                sort: args.sort,
              });

              return data;
            },
          },
        },
      },
    }));
  }
}
cyp3rius commented 1 year ago

Thats one of the way here :) If you are using extensions approach.

As you already got it for your own purposes, may I ask you to contribute and implement similar approach by adding route, controller and service methods? :) Would be really nice.

jnovak-SM2Dev commented 1 year ago

@cyp3rius I would, but I have no idea how. I'm only using GraphQL in my project and this is my first Strapi project. I'm not using routes/controllers/services. I could try and take a look at some point, but i'm not sure where i'd even start with those.

cyp3rius commented 1 year ago

Endpoint + GQL Query published as part of v2.2.11. Hope it fulfils your requirements :)

jnovak-SM2Dev commented 1 year ago

@cyp3rius Sorry, didn't see your last message. Yes it does help a lot. Only one issue, how can I get the related item? I'd need to be able to link to the related item and show related details. For example, if the comment is on a blog post, i'd need to show the title of the blog post and link to it.

Also, the author field does not populate properly.

jnovak-SM2Dev commented 1 year ago

@cyp3rius I add this to my version to allow being able to pull related items.

extensionService.use(({ strapi }) => ({
  typeDefs: `
    union Related = ArticleEntity | PodcastEntity
    type CommentSingle {
      related: Related
    }
  `,
  resolvers: {
    Related: {
      __resolveType(x) {
        switch (x.uid) {
          case "api::article.article": {
            return "ArticleEntity";
          }
          case "api::podcast.podcast": {
            return "PodcastEntity";
          }
          default: {
            return null;
          }
        }
      },
    },
  },
}));