From d217fedf9c18095223beabc0da56341206a594c9 Mon Sep 17 00:00:00 2001 From: Kiwi Date: Fri, 29 Mar 2019 23:29:17 +0100 Subject: [PATCH] [CORL-171] Comment Tags (#2248) * feat: staff badge * feat: added tag support on the server * feat: use tags * fix: server tests --- .../stream/mutations/CreateCommentMutation.ts | 1 + .../mutations/CreateCommentReplyMutation.ts | 1 + .../comments/components/Comment/Comment.tsx | 8 +- .../components/Comment/RootParent.tsx | 8 +- .../__snapshots__/Comment.spec.tsx.snap | 12 +- .../tabs/comments/components/StaffTag.tsx | 6 + .../containers/CommentContainer.spec.tsx | 12 ++ .../comments/containers/CommentContainer.tsx | 4 + .../CommentContainer.spec.tsx.snap | 130 ++++++++++++++++++ .../components/ConversationThread.spec.tsx | 62 ++++----- .../components/ConversationThread.tsx | 2 + .../ConversationThread.spec.tsx.snap | 71 ++++++++++ .../ConversationThreadContainer.tsx | 4 + .../__snapshots__/editComment.spec.tsx.snap | 48 ++++--- .../__snapshots__/loadMore.spec.tsx.snap | 24 ++-- .../__snapshots__/permalinkView.spec.tsx.snap | 60 +++++--- ...permalinkViewLoadMoreParents.spec.tsx.snap | 86 ++++++++---- .../__snapshots__/postComment.spec.tsx.snap | 12 +- .../postLocalReply.spec.tsx.snap | 96 ++++++++----- .../__snapshots__/postReply.spec.tsx.snap | 24 ++-- .../renderCommunityGuidelines.spec.tsx.snap | 24 ++-- .../__snapshots__/renderReplies.spec.tsx.snap | 48 ++++--- .../__snapshots__/renderStream.spec.tsx.snap | 43 ++++-- .../showAllReplies.spec.tsx.snap | 12 +- .../showConversation.spec.tsx.snap | 12 +- .../__snapshots__/sortStream.spec.tsx.snap | 24 ++-- .../comments/charCountEditComment.spec.tsx | 4 +- .../comments/charCountPostComment.spec.tsx | 4 +- .../comments/charCountReplyComment.spec.tsx | 4 +- .../stream/test/comments/editComment.spec.tsx | 4 +- .../permalinkViewLoadMoreParents.spec.tsx | 8 +- .../stream/test/comments/postComment.spec.tsx | 10 +- .../test/comments/postLocalReply.spec.tsx | 6 +- .../stream/test/comments/postReply.spec.tsx | 10 +- .../stream/test/comments/reaction.spec.tsx | 4 +- .../test/comments/renderMessageBox.spec.tsx | 4 +- .../test/comments/renderStream.spec.tsx | 8 +- .../test/comments/reportComment.spec.tsx | 4 +- .../test/configure/openOrCloseStream.spec.tsx | 4 +- .../test/configure/renderConfigure.spec.tsx | 4 +- .../configure/streamConfiguration.spec.tsx | 4 +- src/core/client/stream/test/fixtures.ts | 64 ++++++--- src/core/client/ui/components/Tag/Tag.css | 8 ++ src/core/client/ui/components/Tag/Tag.mdx | 19 +++ .../client/ui/components/Tag/Tag.spec.tsx | 15 ++ src/core/client/ui/components/Tag/Tag.tsx | 31 +++++ .../Tag/__snapshots__/Tag.spec.tsx.snap | 9 ++ src/core/client/ui/components/Tag/index.ts | 1 + src/core/client/ui/components/index.ts | 1 + src/core/client/ui/shared/typography.css | 7 + src/core/server/graph/tenant/resolvers/Tag.ts | 23 ++++ .../server/graph/tenant/resolvers/index.ts | 2 + .../server/graph/tenant/schema/schema.graphql | 26 ++++ src/core/server/locales/en-US/tags.ftl | 2 + .../models/{comment.ts => comment/index.ts} | 14 ++ src/core/server/models/comment/tag.ts | 44 ++++++ src/core/server/services/comments/index.ts | 5 +- .../services/comments/pipeline/index.spec.ts | 3 + .../services/comments/pipeline/index.ts | 14 ++ .../comments/pipeline/phases/staff.ts | 8 ++ 60 files changed, 945 insertions(+), 267 deletions(-) create mode 100644 src/core/client/stream/tabs/comments/components/StaffTag.tsx create mode 100644 src/core/client/ui/components/Tag/Tag.css create mode 100644 src/core/client/ui/components/Tag/Tag.mdx create mode 100644 src/core/client/ui/components/Tag/Tag.spec.tsx create mode 100644 src/core/client/ui/components/Tag/Tag.tsx create mode 100644 src/core/client/ui/components/Tag/__snapshots__/Tag.spec.tsx.snap create mode 100644 src/core/client/ui/components/Tag/index.ts create mode 100644 src/core/server/graph/tenant/resolvers/Tag.ts create mode 100644 src/core/server/locales/en-US/tags.ftl rename src/core/server/models/{comment.ts => comment/index.ts} (98%) create mode 100644 src/core/server/models/comment/tag.ts diff --git a/src/core/client/stream/mutations/CreateCommentMutation.ts b/src/core/client/stream/mutations/CreateCommentMutation.ts index de69a4446..1d4ba4065 100644 --- a/src/core/client/stream/mutations/CreateCommentMutation.ts +++ b/src/core/client/stream/mutations/CreateCommentMutation.ts @@ -152,6 +152,7 @@ function commit( total: 0, }, }, + tags: [], }, }, clientMutationId: (clientMutationId++).toString(), diff --git a/src/core/client/stream/mutations/CreateCommentReplyMutation.ts b/src/core/client/stream/mutations/CreateCommentReplyMutation.ts index 09746dfc4..023d49123 100644 --- a/src/core/client/stream/mutations/CreateCommentReplyMutation.ts +++ b/src/core/client/stream/mutations/CreateCommentReplyMutation.ts @@ -181,6 +181,7 @@ function commit( total: 0, }, }, + tags: [], }, }, clientMutationId: (clientMutationId++).toString(), diff --git a/src/core/client/stream/tabs/comments/components/Comment/Comment.tsx b/src/core/client/stream/tabs/comments/components/Comment/Comment.tsx index 39955769e..e09c239b6 100644 --- a/src/core/client/stream/tabs/comments/components/Comment/Comment.tsx +++ b/src/core/client/stream/tabs/comments/components/Comment/Comment.tsx @@ -3,7 +3,7 @@ import React, { StatelessComponent } from "react"; import HTMLContent from "talk-stream/components/HTMLContent"; import Timestamp from "talk-stream/components/Timestamp"; -import { Flex, HorizontalGutter } from "talk-ui/components"; +import { Flex, HorizontalGutter, Tag } from "talk-ui/components"; import EditedMarker from "./EditedMarker"; import InReplyTo from "./InReplyTo"; @@ -22,6 +22,7 @@ export interface CommentProps { showEditedMarker?: boolean; highlight?: boolean; parentAuthorName?: string | null; + tags?: ReadonlyArray; } const Comment: StatelessComponent = props => { @@ -32,7 +33,10 @@ const Comment: StatelessComponent = props => { > - {props.username && {props.username}} + + {props.username && {props.username}} + {props.tags && props.tags.map((t, i) => {t})} + {props.createdAt} {props.showEditedMarker && } diff --git a/src/core/client/stream/tabs/comments/components/Comment/RootParent.tsx b/src/core/client/stream/tabs/comments/components/Comment/RootParent.tsx index 04134c7ee..6b515b64c 100644 --- a/src/core/client/stream/tabs/comments/components/Comment/RootParent.tsx +++ b/src/core/client/stream/tabs/comments/components/Comment/RootParent.tsx @@ -1,7 +1,7 @@ import React, { StatelessComponent } from "react"; import Timestamp from "talk-stream/components/Timestamp"; -import { Flex } from "talk-ui/components"; +import { Flex, Tag } from "talk-ui/components"; import TopBarLeft from "./TopBarLeft"; import Username from "./Username"; @@ -10,13 +10,17 @@ export interface RootParentProps { id?: string; username: string | null; createdAt: string; + tags?: ReadonlyArray; } const RootParent: StatelessComponent = props => { return ( - {props.username && {props.username}} + + {props.username && {props.username}} + {props.tags && props.tags.map((t, i) => {t})} + {props.createdAt} diff --git a/src/core/client/stream/tabs/comments/components/Comment/__snapshots__/Comment.spec.tsx.snap b/src/core/client/stream/tabs/comments/components/Comment/__snapshots__/Comment.spec.tsx.snap index 3a58a318e..a544ff0bd 100644 --- a/src/core/client/stream/tabs/comments/components/Comment/__snapshots__/Comment.spec.tsx.snap +++ b/src/core/client/stream/tabs/comments/components/Comment/__snapshots__/Comment.spec.tsx.snap @@ -10,9 +10,15 @@ exports[`renders username and body 1`] = ` justifyContent="space-between" > - - Marvin - + + + Marvin + +
; +export default Divider; diff --git a/src/core/client/stream/tabs/comments/containers/CommentContainer.spec.tsx b/src/core/client/stream/tabs/comments/containers/CommentContainer.spec.tsx index 174714404..1e324bd76 100644 --- a/src/core/client/stream/tabs/comments/containers/CommentContainer.spec.tsx +++ b/src/core/client/stream/tabs/comments/containers/CommentContainer.spec.tsx @@ -36,6 +36,7 @@ function createDefaultProps(add: DeepPartial = {}): Props { editableUntil: "1995-12-17T03:24:30.000Z", }, pending: false, + tags: [], }, settings: { disableCommenting: { @@ -128,3 +129,14 @@ it("renders disabled reply when commenting has been disabled", () => { renderer.render(); expect(renderer.getRenderOutput()).toMatchSnapshot(); }); + +it("renders staff badge", () => { + const props = createDefaultProps({ + comment: { + tags: [{ name: "Staff" }], + }, + }); + const renderer = createRenderer(); + renderer.render(); + expect(renderer.getRenderOutput()).toMatchSnapshot(); +}); diff --git a/src/core/client/stream/tabs/comments/containers/CommentContainer.tsx b/src/core/client/stream/tabs/comments/containers/CommentContainer.tsx index 2598fdd95..5a7890156 100644 --- a/src/core/client/stream/tabs/comments/containers/CommentContainer.tsx +++ b/src/core/client/stream/tabs/comments/containers/CommentContainer.tsx @@ -182,6 +182,7 @@ export class CommentContainer extends Component { comment.parent.author && comment.parent.author.username } + tags={comment.tags.map(t => t.name)} topBarRight={ (editable && ( @@ -294,6 +295,9 @@ const enhanced = withSetCommentIDMutation( edited editableUntil } + tags { + name + } pending ...ReplyCommentFormContainer_comment ...EditCommentFormContainer_comment diff --git a/src/core/client/stream/tabs/comments/containers/__snapshots__/CommentContainer.spec.tsx.snap b/src/core/client/stream/tabs/comments/containers/__snapshots__/CommentContainer.spec.tsx.snap index 28872406a..3f02ef848 100644 --- a/src/core/client/stream/tabs/comments/containers/__snapshots__/CommentContainer.spec.tsx.snap +++ b/src/core/client/stream/tabs/comments/containers/__snapshots__/CommentContainer.spec.tsx.snap @@ -41,6 +41,7 @@ exports[`hide reply button 1`] = ` "parent": null, "pending": false, "status": "NONE", + "tags": Array [], } } settings={ @@ -71,6 +72,7 @@ exports[`hide reply button 1`] = ` "parent": null, "pending": false, "status": "NONE", + "tags": Array [], } } viewer={null} @@ -82,6 +84,7 @@ exports[`hide reply button 1`] = ` indentLevel={1} parentAuthorName={null} showEditedMarker={false} + tags={Array []} username="Marvin" />
@@ -135,6 +138,7 @@ exports[`renders body only 1`] = ` "parent": null, "pending": false, "status": "NONE", + "tags": Array [], } } settings={ @@ -165,6 +169,7 @@ exports[`renders body only 1`] = ` "parent": null, "pending": false, "status": "NONE", + "tags": Array [], } } viewer={null} @@ -176,6 +181,7 @@ exports[`renders body only 1`] = ` indentLevel={1} parentAuthorName={null} showEditedMarker={false} + tags={Array []} username={null} /> @@ -229,6 +235,7 @@ exports[`renders disabled reply when commenting has been disabled 1`] = ` "parent": null, "pending": false, "status": "NONE", + "tags": Array [], } } settings={ @@ -259,6 +266,7 @@ exports[`renders disabled reply when commenting has been disabled 1`] = ` "parent": null, "pending": false, "status": "NONE", + "tags": Array [], } } viewer={null} @@ -270,6 +278,7 @@ exports[`renders disabled reply when commenting has been disabled 1`] = ` indentLevel={1} parentAuthorName={null} showEditedMarker={false} + tags={Array []} username="Marvin" /> @@ -323,6 +332,7 @@ exports[`renders disabled reply when story is closed 1`] = ` "parent": null, "pending": false, "status": "NONE", + "tags": Array [], } } settings={ @@ -353,6 +363,7 @@ exports[`renders disabled reply when story is closed 1`] = ` "parent": null, "pending": false, "status": "NONE", + "tags": Array [], } } viewer={null} @@ -364,6 +375,7 @@ exports[`renders disabled reply when story is closed 1`] = ` indentLevel={1} parentAuthorName={null} showEditedMarker={false} + tags={Array []} username="Marvin" /> @@ -421,6 +433,7 @@ exports[`renders in reply to 1`] = ` }, "pending": false, "status": "NONE", + "tags": Array [], } } settings={ @@ -455,6 +468,7 @@ exports[`renders in reply to 1`] = ` }, "pending": false, "status": "NONE", + "tags": Array [], } } viewer={null} @@ -466,6 +480,116 @@ exports[`renders in reply to 1`] = ` indentLevel={1} parentAuthorName="ParentAuthor" showEditedMarker={false} + tags={Array []} + username="Marvin" + /> + + +`; + +exports[`renders staff badge 1`] = ` +
+ + + + + + + + + + + + + + } + indentLevel={1} + parentAuthorName={null} + showEditedMarker={false} + tags={ + Array [ + "Staff", + ] + } username="Marvin" /> @@ -519,6 +643,7 @@ exports[`renders username and body 1`] = ` "parent": null, "pending": false, "status": "NONE", + "tags": Array [], } } settings={ @@ -549,6 +674,7 @@ exports[`renders username and body 1`] = ` "parent": null, "pending": false, "status": "NONE", + "tags": Array [], } } viewer={null} @@ -560,6 +686,7 @@ exports[`renders username and body 1`] = ` indentLevel={1} parentAuthorName={null} showEditedMarker={false} + tags={Array []} username="Marvin" /> @@ -613,6 +740,7 @@ exports[`shows conversation link 1`] = ` "parent": null, "pending": false, "status": "NONE", + "tags": Array [], } } settings={ @@ -643,6 +771,7 @@ exports[`shows conversation link 1`] = ` "parent": null, "pending": false, "status": "NONE", + "tags": Array [], } } viewer={null} @@ -659,6 +788,7 @@ exports[`shows conversation link 1`] = ` indentLevel={1} parentAuthorName={null} showEditedMarker={false} + tags={Array []} username="Marvin" /> diff --git a/src/core/client/stream/tabs/comments/views/permalink/components/ConversationThread.spec.tsx b/src/core/client/stream/tabs/comments/views/permalink/components/ConversationThread.spec.tsx index 0f294c2e7..ba0f00dbb 100644 --- a/src/core/client/stream/tabs/comments/views/permalink/components/ConversationThread.spec.tsx +++ b/src/core/client/stream/tabs/comments/views/permalink/components/ConversationThread.spec.tsx @@ -1,17 +1,20 @@ -import { noop } from "lodash"; +import { merge, noop } from "lodash"; import React from "react"; import { createRenderer } from "react-test-renderer/shallow"; -import { PropTypesOf } from "talk-framework/types"; +import { DeepPartial, PropTypesOf } from "talk-framework/types"; import { removeFragmentRefs } from "talk-framework/testHelpers"; import ConversationThread from "./ConversationThread"; const ConversationThreadN = removeFragmentRefs(ConversationThread); -describe("with 2 remaining parent comments", () => { - it("renders correctly", () => { - const props: PropTypesOf = { +type Props = PropTypesOf; + +function createDefaultProps(add: DeepPartial = {}): Props { + return merge( + {}, + { className: "root", viewer: {}, story: {}, @@ -25,29 +28,34 @@ describe("with 2 remaining parent comments", () => { id: "root-parent", createdAt: "1995-12-17T03:24:00.000Z", username: "parentAuthor", + tags: [], }, - }; + }, + add + ); +} + +describe("with 2 remaining parent comments", () => { + it("renders correctly", () => { + const props = createDefaultProps(); + const renderer = createRenderer(); + renderer.render(); + expect(renderer.getRenderOutput()).toMatchSnapshot(); + }); + it("renders staff badge", () => { + const props = createDefaultProps({ + rootParent: { + tags: ["Staff"], + }, + }); const renderer = createRenderer(); renderer.render(); expect(renderer.getRenderOutput()).toMatchSnapshot(); }); it("renders with disabled load more", () => { - const props: PropTypesOf = { - className: "root", - viewer: {}, - story: {}, - settings: {}, - comment: {}, + const props = createDefaultProps({ disableLoadMore: true, - loadMore: noop, - remaining: 2, - parents: [], - rootParent: { - id: "root-parent", - createdAt: "1995-12-17T03:24:00.000Z", - username: "parentAuthor", - }, - }; + }); const renderer = createRenderer(); renderer.render(); expect(renderer.getRenderOutput()).toMatchSnapshot(); @@ -55,18 +63,10 @@ describe("with 2 remaining parent comments", () => { }); it("renders with no parent comments", () => { - const props: PropTypesOf = { - className: "root", - viewer: {}, - story: {}, - settings: {}, - comment: {}, - disableLoadMore: false, - loadMore: noop, + const props = createDefaultProps({ remaining: 0, - parents: [], rootParent: null, - }; + }); const renderer = createRenderer(); renderer.render(); expect(renderer.getRenderOutput()).toMatchSnapshot(); diff --git a/src/core/client/stream/tabs/comments/views/permalink/components/ConversationThread.tsx b/src/core/client/stream/tabs/comments/views/permalink/components/ConversationThread.tsx index 5d1c31852..97910cdc8 100644 --- a/src/core/client/stream/tabs/comments/views/permalink/components/ConversationThread.tsx +++ b/src/core/client/stream/tabs/comments/views/permalink/components/ConversationThread.tsx @@ -32,6 +32,7 @@ export interface ConversationThreadProps { id: string; createdAt: string; username: string | null; + tags: ReadonlyArray; } | null; } @@ -64,6 +65,7 @@ const ConversationThread: StatelessComponent< id={props.rootParent.id} username={props.rootParent.username} createdAt={props.rootParent.createdAt} + tags={props.rootParent.tags} /> )} diff --git a/src/core/client/stream/tabs/comments/views/permalink/components/__snapshots__/ConversationThread.spec.tsx.snap b/src/core/client/stream/tabs/comments/views/permalink/components/__snapshots__/ConversationThread.spec.tsx.snap index 91089af26..a4c7391ba 100644 --- a/src/core/client/stream/tabs/comments/views/permalink/components/__snapshots__/ConversationThread.spec.tsx.snap +++ b/src/core/client/stream/tabs/comments/views/permalink/components/__snapshots__/ConversationThread.spec.tsx.snap @@ -31,6 +31,76 @@ exports[`with 2 remaining parent comments renders correctly 1`] = ` + + + + + + Show more of this conversation + + + + 2 + + + + + + + + + +
+`; + +exports[`with 2 remaining parent comments renders staff badge 1`] = ` +
+ + } + > + + @@ -95,6 +165,7 @@ exports[`with 2 remaining parent comments renders with disabled load more 1`] = diff --git a/src/core/client/stream/tabs/comments/views/permalink/containers/ConversationThreadContainer.tsx b/src/core/client/stream/tabs/comments/views/permalink/containers/ConversationThreadContainer.tsx index cb0d6f53c..fbf81604c 100644 --- a/src/core/client/stream/tabs/comments/views/permalink/containers/ConversationThreadContainer.tsx +++ b/src/core/client/stream/tabs/comments/views/permalink/containers/ConversationThreadContainer.tsx @@ -71,6 +71,7 @@ class ConversationThreadContainer extends React.Component< createdAt: comment.rootParent.createdAt, username: comment.rootParent.author && comment.rootParent.author.username, + tags: comment.rootParent.tags.map(t => t.name), }) || null } @@ -122,6 +123,9 @@ const enhanced = withContext(ctx => ({ username } createdAt + tags { + name + } } parentCount parents(last: $count, before: $cursor) diff --git a/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap index 98ee01990..1912fd4e9 100644 --- a/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap @@ -23,11 +23,15 @@ exports[`cancel edit 1`] = `
- - Markus - + + Markus + +
@@ -702,11 +706,15 @@ exports[`edit a comment: render comment with edit button 1`] = `
- - Markus - + + Markus + +
@@ -883,11 +891,15 @@ exports[`edit a comment: server response 1`] = `
- - Markus - + + Markus + +
@@ -1073,11 +1085,15 @@ exports[`shows expiry message: edit form closed 1`] = `
- - Markus - + + Markus + +
diff --git a/src/core/client/stream/test/comments/__snapshots__/loadMore.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/loadMore.spec.tsx.snap index 0d0653184..9b3a783bc 100644 --- a/src/core/client/stream/test/comments/__snapshots__/loadMore.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/loadMore.spec.tsx.snap @@ -33,11 +33,15 @@ exports[`renders comment stream with load more button 1`] = `
- - Markus - + + Markus + +
@@ -183,11 +187,15 @@ exports[`renders comment stream with load more button 1`] = `
- - Lukas - + + Lukas + +
diff --git a/src/core/client/stream/test/comments/__snapshots__/permalinkView.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/permalinkView.spec.tsx.snap index c13f3ff86..19dee528f 100644 --- a/src/core/client/stream/test/comments/__snapshots__/permalinkView.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/permalinkView.spec.tsx.snap @@ -120,11 +120,15 @@ exports[`renders permalink view 1`] = `
- - Lukas - + + Lukas + +
@@ -287,11 +291,15 @@ exports[`renders permalink view 1`] = `
- - Isabelle - + + Isabelle + +
@@ -452,11 +460,15 @@ exports[`renders permalink view 1`] = `
- - Markus - + + Markus + +
@@ -613,11 +625,15 @@ exports[`renders permalink view 1`] = `
- - Isabelle - + + Isabelle + +
@@ -763,11 +779,15 @@ exports[`renders permalink view 1`] = `
- - Isabelle - + + Isabelle + +
diff --git a/src/core/client/stream/test/comments/__snapshots__/permalinkViewLoadMoreParents.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/permalinkViewLoadMoreParents.spec.tsx.snap index 48c9ac72a..f41f05474 100644 --- a/src/core/client/stream/test/comments/__snapshots__/permalinkViewLoadMoreParents.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/permalinkViewLoadMoreParents.spec.tsx.snap @@ -28,16 +28,25 @@ exports[`renders conversation thread 1`] = `
- - Isabelle - + + Moderator + + + Staff + +
@@ -143,11 +152,15 @@ exports[`renders conversation thread 1`] = `
- - Markus - + + Markus + +
@@ -323,11 +336,15 @@ exports[`shows more of this conversation 1`] = `
- - Lukas - + + Lukas + +
@@ -469,7 +486,7 @@ exports[`shows more of this conversation 1`] = `
- - Isabelle - + + Moderator + + + Staff + +
@@ -515,7 +541,7 @@ exports[`shows more of this conversation 1`] = ` className="HTMLContent-root" dangerouslySetInnerHTML={ Object { - "__html": "Hey!", + "__html": "Joining Too", } } /> @@ -528,7 +554,7 @@ exports[`shows more of this conversation 1`] = `