Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions packages/api/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ type Comment {
published: Boolean!
}

type PaperComment {
text: String!
userId: ID!
lastName: String!
firstName: String!
published: Boolean!
}

"""
An object that can have comments
"""
Expand Down Expand Up @@ -125,6 +133,7 @@ input PaperEntryInput {
question: String!
answer: String
hint: String
comments: [PaperCommentInput!]!
}

type MutatePaperPayload {
Expand Down Expand Up @@ -502,6 +511,14 @@ type Report implements CommentableInterface {
nextReportLink: String
}

input PaperCommentInput {
text: String!
userId: ID!
firstName: String!
lastName: String!
published: Boolean!
}

"""
Represents the current state of the report
"""
Expand Down Expand Up @@ -729,6 +746,7 @@ type PaperFormData {
question: String!
answer: String
hint: String
comments: [PaperComment!]!
}

type Paper {
Expand Down
34 changes: 34 additions & 0 deletions packages/api/src/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -562,8 +562,26 @@ export type GqlPaper = {
trainerId: Scalars['ID']['output'];
};

export type GqlPaperComment = {
__typename?: 'PaperComment';
firstName: Scalars['String']['output'];
lastName: Scalars['String']['output'];
published: Scalars['Boolean']['output'];
text: Scalars['String']['output'];
userId: Scalars['ID']['output'];
};

export type GqlPaperCommentInput = {
firstName: Scalars['String']['input'];
lastName: Scalars['String']['input'];
published: Scalars['Boolean']['input'];
text: Scalars['String']['input'];
userId: Scalars['ID']['input'];
};

export type GqlPaperEntryInput = {
answer?: InputMaybe<Scalars['String']['input']>;
comments: Array<GqlPaperCommentInput>;
hint?: InputMaybe<Scalars['String']['input']>;
id: Scalars['ID']['input'];
question: Scalars['String']['input'];
Expand All @@ -573,6 +591,7 @@ export type GqlPaperEntryInput = {
export type GqlPaperFormData = {
__typename?: 'PaperFormData';
answer?: Maybe<Scalars['String']['output']>;
comments: Array<GqlPaperComment>;
hint?: Maybe<Scalars['String']['output']>;
id: Scalars['ID']['output'];
question: Scalars['String']['output'];
Expand Down Expand Up @@ -957,6 +976,8 @@ export type GqlResolversTypes = ResolversObject<{
Mutation: ResolverTypeWrapper<{}>;
OAuthPayload: ResolverTypeWrapper<GqlOAuthPayload>;
Paper: ResolverTypeWrapper<Paper>;
PaperComment: ResolverTypeWrapper<GqlPaperComment>;
PaperCommentInput: GqlPaperCommentInput;
PaperEntryInput: GqlPaperEntryInput;
PaperFormData: ResolverTypeWrapper<GqlPaperFormData>;
PaperInput: GqlPaperInput;
Expand Down Expand Up @@ -1012,6 +1033,8 @@ export type GqlResolversParentTypes = ResolversObject<{
Mutation: {};
OAuthPayload: GqlOAuthPayload;
Paper: Paper;
PaperComment: GqlPaperComment;
PaperCommentInput: GqlPaperCommentInput;
PaperEntryInput: GqlPaperEntryInput;
PaperFormData: GqlPaperFormData;
PaperInput: GqlPaperInput;
Expand Down Expand Up @@ -1229,8 +1252,18 @@ export type GqlPaperResolvers<ContextType = Context, ParentType extends GqlResol
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
}>;

export type GqlPaperCommentResolvers<ContextType = Context, ParentType extends GqlResolversParentTypes['PaperComment'] = GqlResolversParentTypes['PaperComment']> = ResolversObject<{
firstName?: Resolver<GqlResolversTypes['String'], ParentType, ContextType>;
lastName?: Resolver<GqlResolversTypes['String'], ParentType, ContextType>;
published?: Resolver<GqlResolversTypes['Boolean'], ParentType, ContextType>;
text?: Resolver<GqlResolversTypes['String'], ParentType, ContextType>;
userId?: Resolver<GqlResolversTypes['ID'], ParentType, ContextType>;
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
}>;

export type GqlPaperFormDataResolvers<ContextType = Context, ParentType extends GqlResolversParentTypes['PaperFormData'] = GqlResolversParentTypes['PaperFormData']> = ResolversObject<{
answer?: Resolver<Maybe<GqlResolversTypes['String']>, ParentType, ContextType>;
comments?: Resolver<Array<GqlResolversTypes['PaperComment']>, ParentType, ContextType>;
hint?: Resolver<Maybe<GqlResolversTypes['String']>, ParentType, ContextType>;
id?: Resolver<GqlResolversTypes['ID'], ParentType, ContextType>;
question?: Resolver<GqlResolversTypes['String'], ParentType, ContextType>;
Expand Down Expand Up @@ -1384,6 +1417,7 @@ export type GqlResolvers<ContextType = Context> = ResolversObject<{
Mutation?: GqlMutationResolvers<ContextType>;
OAuthPayload?: GqlOAuthPayloadResolvers<ContextType>;
Paper?: GqlPaperResolvers<ContextType>;
PaperComment?: GqlPaperCommentResolvers<ContextType>;
PaperFormData?: GqlPaperFormDataResolvers<ContextType>;
PrintPayload?: GqlPrintPayloadResolvers<ContextType>;
PublishCommentsPayload?: GqlPublishCommentsPayloadResolvers<ContextType>;
Expand Down
11 changes: 10 additions & 1 deletion packages/backend/src/resolvers/user.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { AuthenticatedContext, GqlResolvers, User } from '@lara/api'

import { isAdmin, isTrainee, isTrainer } from '../permissions'
import { isAdmin, isTrainee, isTrainer, isMentor } from '../permissions'
import { allTrainees } from '../repositories/trainee.repo'
import { saveUser } from '../repositories/user.repo'
import { generateAdmin } from '../services/admin.service'
import { alexaSkillLinked } from '../services/alexa.service'
import { generateTrainee } from '../services/trainee.service'
import { generateTrainer } from '../services/trainer.service'
import { generateMentor } from '../services/mentor.service'

export const userResolver: GqlResolvers<AuthenticatedContext> = {
UserInterface: {
Expand Down Expand Up @@ -41,6 +42,14 @@ export const userResolver: GqlResolvers<AuthenticatedContext> = {
}
}

if (!isMentor(currentUser) && type === 'Mentor') {
newUser = {
...(await generateMentor(currentUser)),
...currentUser,
type,
}
}

if (!isAdmin(currentUser) && type === 'Admin') {
newUser = {
...generateAdmin(currentUser),
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/comment-bubble-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export const CommentBubbleLayout: React.FC<CommentBubbleLayoutProps> = ({
return (
<MessageContainer right={right}>
<Bubble right={right}>
<Author>{author}:</Author>
<Author>{author}</Author>
{updateMessage ? (
<MessageInput
value={msg}
Expand Down
64 changes: 54 additions & 10 deletions packages/frontend/src/components/comment-box.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import React from 'react'

import { Comment, useCommentBoxDataQuery, UserInterface } from '../graphql'
import { Comment, PaperComment, useCommentBoxDataQuery, UserInterface } from '../graphql'
import CommentBubble from './comment-bubble'
import Loader from './loader'

type TransformedCommentArray =
| Array<
Pick<Comment, 'id' | 'text' | 'published'> & {
user: Pick<UserInterface, 'id' | 'firstName' | 'lastName'>
}
>
| Array<Pick<PaperComment, 'text' | 'published' | 'lastName' | 'firstName' | 'userId'>>

type TransformedComment =
| (Pick<Comment, 'id' | 'text' | 'published'> & {
user: Pick<UserInterface, 'id' | 'firstName' | 'lastName'>
})
| Pick<PaperComment, 'text' | 'published' | 'lastName' | 'firstName' | 'userId'>

interface CommentBoxProps {
comments?: (Pick<Comment, 'text' | 'id' | 'published'> & {
user: Pick<UserInterface, 'id' | 'firstName' | 'lastName'>
})[]
comments?: TransformedCommentArray
updateMessage?: (message: string, commentId: string) => void
}

Expand All @@ -20,18 +32,50 @@ const CommentBox: React.FunctionComponent<CommentBoxProps> = ({ comments, update

const { currentUser } = data

const getFirstName = (comment: TransformedComment) => {
if ('user' in comment) {
return comment.user.firstName
} else {
return comment.firstName
}
}

const getLastName = (comment: TransformedComment) => {
if ('user' in comment) {
return comment.user.lastName
} else {
return comment.lastName
}
}

const getUserId = (comment: TransformedComment) => {
if ('user' in comment) {
return comment.user.id
} else {
return comment.userId
}
}

const getId = (comment: TransformedComment) => {
if ('id' in comment) {
return comment.id
} else {
return comment.userId
}
}

return (
<>
{comments
? comments.map((comment) => (
<CommentBubble
key={comment.id}
author={`${comment.user.firstName} ${comment.user.lastName}`}
key={getId(comment)}
author={`${getFirstName(comment)} ${getLastName(comment)}`}
message={comment.text}
id={comment.user.id}
right={comment.user.id !== currentUser?.id}
updateMessage={comment.user.id === currentUser?.id && !comment.published ? updateMessage : undefined}
commentId={comment.id}
id={getUserId(comment)}
right={getUserId(comment) !== currentUser?.id}
updateMessage={getUserId(comment) === currentUser?.id && !comment.published ? updateMessage : undefined}
commentId={getId(comment)}
/>
))
: null}
Expand Down
18 changes: 13 additions & 5 deletions packages/frontend/src/components/comment-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,24 @@ import { useForm } from 'react-hook-form'

import { ErrorText, Input, Spacer, StyledTextInputLabel } from '@lara/components'

import { Comment, UserInterface } from '../graphql'
import { Comment, PaperComment, UserInterface } from '../graphql'
import strings from '../locales/localization'
import CommentBox from './comment-box'

type TransformedCommentArray =
| Array<
Pick<Comment, 'id' | 'text' | 'published'> & {
user: Pick<UserInterface, 'id' | 'firstName' | 'lastName'>
}
>
| Array<Pick<PaperComment, 'text' | 'published' | 'lastName' | 'firstName' | 'userId'>>

interface CommentSectionProps {
comments: (Pick<Comment, 'id' | 'text' | 'published'> & {
user: Pick<UserInterface, 'id' | 'firstName' | 'lastName'>
})[]
comments: TransformedCommentArray
onSubmit: onSubmitType
displayTextInput: boolean
bottomSpace?: boolean
spacingM?: boolean
updateMessage?: (message: string, commentId: string) => void
}

Expand All @@ -23,6 +30,7 @@ const CommentSection: React.FunctionComponent<CommentSectionProps> = ({
comments,
bottomSpace,
displayTextInput,
spacingM,
onSubmit: submit,
updateMessage,
}) => {
Expand All @@ -43,7 +51,7 @@ const CommentSection: React.FunctionComponent<CommentSectionProps> = ({
<>
<CommentBox comments={comments} updateMessage={updateMessage} />
{displayTextInput && (
<Spacer x="l" bottom={bottomSpace ? 'l' : undefined}>
<Spacer x={spacingM ? 'm' : 'l'} bottom={bottomSpace ? 'l' : undefined}>
<form onSubmit={onSubmit} onBlur={onSubmit}>
<StyledTextInputLabel valid={!errors.comment}>{strings.report.comments.addComment}</StyledTextInputLabel>
<Input
Expand Down
1 change: 1 addition & 0 deletions packages/frontend/src/components/paper-text-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const PaperTextInput: React.FC<PaperTextInputProps> = ({
question: entry.question,
id: entry.id,
hint: entry.hint ? entry.hint : '',
comments: [],
})
}

Expand Down
Loading
Loading