Skip to content

Commit

Permalink
[EASI-4639] Discussions panel views (#2895)
Browse files Browse the repository at this point in the history
* Merge discussions card work into branch

* Discussions panel view components

* Discussion post and reply mutations

* Basic discussion form

* Fix line height within side panel

* Display discussion and replies

* Discussions list view

* Threaded replies styling

* Show/hide replies

* DiscussionsList component

* Add DiscussionsList to Discussion view

* Add DiscussionsList to discussion board view

* Create discussion and reply mutations

* Discussion board list filtering

* ViewDiscussions unit tests

* Discussion component unit tests

* Success and error messages

* Feature branch merge conflict fix

* MentionTextArea in DiscussionForm (#2898)

* MentionTextArea in DiscussionForm

* Mention area height-auto

* Text

* Rhf-like signature

* .usa-textarea + overrides

* Cleanup

* MentionTextArea React.forwardRef

* Cleanup

* Fix render error when review has no discussions

* Hide replies if array is empty

---------

Co-authored-by: adamodd <97050498+adamodd@users.noreply.github.com>
  • Loading branch information
aterstriep and adamodd authored Nov 22, 2024
1 parent 95efd7c commit 820a81d
Show file tree
Hide file tree
Showing 26 changed files with 1,214 additions and 176 deletions.
15 changes: 12 additions & 3 deletions src/components/MentionTextArea/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

/* Basic editor styles */
.tiptap {
border: 1px solid black;
padding: .5rem;

p {
margin: 0px;
}
Expand Down Expand Up @@ -45,6 +42,18 @@
font-size: 16px;
line-height: 22px;
}

&.usa-textarea {
padding: 0;

div[contenteditable] {
font-family: inherit;
font-size: inherit;
line-height: inherit;
height: inherit;
padding: .5rem;
}
}
}
}

Expand Down
159 changes: 79 additions & 80 deletions src/components/MentionTextArea/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
// import { useTranslation } from 'react-i18next';
import Mention from '@tiptap/extension-mention';
import {
Expand All @@ -10,7 +11,6 @@ import {
import StarterKit from '@tiptap/starter-kit';
import classNames from 'classnames';

// import { sortBy } from 'lodash';
import Alert from 'components/shared/Alert';

import suggestion from './suggestion';
Expand Down Expand Up @@ -58,62 +58,57 @@ const CustomMention = Mention.extend({
}
});

const MentionTextArea = ({
id,
setFieldValue,
editable,
disabled,
initialContent,
className
}: {
id: string;
setFieldValue?: (
field: string,
value: any,
shouldValidate?: boolean | undefined
) => void;
editable?: boolean;
disabled?: boolean;
initialContent?: any;
className?: string;
}) => {
// const { t } = useTranslation('');
const MentionTextArea = React.forwardRef<
HTMLDivElement,
{
id: string;
setFieldValue?: (value: any, shouldValidate?: boolean | undefined) => void;
editable?: boolean;
disabled?: boolean;
initialContent?: string;
className?: string;
}
>(
(
{ id, setFieldValue, editable, disabled, initialContent, className },
ref
) => {
const { t } = useTranslation('discussions');

const [tagAlert, setTagAlert] = useState<boolean>(false);
const [tagAlert, setTagAlert] = useState<boolean>(false);

const fetchUsers = ({ query }: { query: string }) => {
return [
{ username: 'a', displayName: 'Admin lead', tagType: 'other' },
{
username: 'b',
displayName: 'Governance Admin Team',
tagType: 'other'
},
{
username: 'c',
displayName: 'Governance Review Board (GRB)',
tagType: 'other'
},
{
username: 'OSYC',
displayName: 'Grant Eliezer',
tagType: 'user'
},
{
username: 'MKCK',
displayName: 'Forest Brown',
tagType: 'user'
},
{
username: 'PJEA',
displayName: 'Janae Stokes',
tagType: 'user'
}
];
};
const fetchUsers = ({ query }: { query: string }) => {
return [
{ username: 'a', displayName: 'Admin lead', tagType: 'other' },
{
username: 'b',
displayName: 'Governance Admin Team',
tagType: 'other'
},
{
username: 'c',
displayName: 'Governance Review Board (GRB)',
tagType: 'other'
},
{
username: 'OSYC',
displayName: 'Grant Eliezer',
tagType: 'user'
},
{
username: 'MKCK',
displayName: 'Forest Brown',
tagType: 'user'
},
{
username: 'PJEA',
displayName: 'Janae Stokes',
tagType: 'user'
}
];
};

const editor = useEditor(
{
const editor = useEditor({
editable: editable && !disabled,
editorProps: {
attributes: {
Expand All @@ -132,41 +127,45 @@ const MentionTextArea = ({
}
})
],
onUpdate: ({ editor: input }: any) => {
// Uses the form setter prop (Formik) for mutation input
onUpdate: ({ editor: input }) => {
const inputContent = input?.getHTML();
const inputText = input?.getText();

if (setFieldValue) {
setFieldValue('content', input?.getHTML());
if (inputText === '') {
setFieldValue('');
return;
}
setFieldValue(inputContent);
}
},
// Sets a alert of a mention is selected, and users/teams will be emailed
onSelectionUpdate: ({ editor: input }: any) => {
setTagAlert(!!getMentions(input?.getJSON()).length);
},
content: initialContent
},
[initialContent, disabled]
);
});

return (
<>
<EditorContent
editor={editor}
id={id}
className={classNames(className, {
tiptap__readonly: !editable,
tiptap__editable: editable
})}
/>
return (
<>
<EditorContent
innerRef={ref}
editor={editor}
id={id}
className={classNames(className, 'usa-textarea', {
tiptap__readonly: !editable,
tiptap__editable: editable
})}
/>

{tagAlert && editable && (
<Alert type="info" slim>
{/* t() */}
When you save your discussion, the selected team(s) and individual(s)
will be notified via email.
</Alert>
)}
</>
);
};
{tagAlert && editable && (
<Alert type="info" slim>
{t('general.alerts.saveDiscussion')}
</Alert>
)}
</>
);
}
);

export default MentionTextArea;
80 changes: 78 additions & 2 deletions src/data/mock/discussions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
import { systemIntake } from './systemIntake';
import users from './users';

const mockDiscussions = (
export const mockDiscussions = (
systemIntakeID: string = systemIntake.id
): SystemIntakeGRBReviewDiscussionFragment[] => [
{
Expand Down Expand Up @@ -62,4 +62,80 @@ const mockDiscussions = (
}
];

export default mockDiscussions;
export const mockDiscussionsWithoutReplies = (
systemIntakeID: string = systemIntake.id
): SystemIntakeGRBReviewDiscussionFragment[] => [
{
__typename: 'SystemIntakeGRBReviewDiscussion',
initialPost: {
__typename: 'SystemIntakeGRBReviewDiscussionPost',
id: 'd6cd88e2-d330-4b7c-9006-d6cf95b775e9',
content: '<p>This is a discussion without replies.</p>',
votingRole: SystemIntakeGRBReviewerVotingRole.NON_VOTING,
grbRole: SystemIntakeGRBReviewerRole.CCIIO_REP,
createdByUserAccount: {
__typename: 'UserAccount',
id: '3f750a9d-a2a2-414f-a013-59554ed32c75',
commonName: users[2].commonName
},
systemIntakeID,
createdAt: '2024-11-18T10:00:00.368862Z'
},
replies: []
},
{
__typename: 'SystemIntakeGRBReviewDiscussion',
initialPost: {
__typename: 'SystemIntakeGRBReviewDiscussionPost',
id: '372bf1c0-3f33-4046-a973-bc063f39dc59',
content: '<p>This is another discussion without replies.</p>',
votingRole: SystemIntakeGRBReviewerVotingRole.VOTING,
grbRole: SystemIntakeGRBReviewerRole.CO_CHAIR_HCA,
createdByUserAccount: {
__typename: 'UserAccount',
id: '32c29aac-e20c-4fce-9ecb-8eb2f4c87e5f',
commonName: users[9].commonName
},
systemIntakeID,
createdAt: '2024-11-17T10:00:00.368862Z'
},
replies: []
},
{
__typename: 'SystemIntakeGRBReviewDiscussion',
initialPost: {
__typename: 'SystemIntakeGRBReviewDiscussionPost',
id: '39823b79-987d-4f81-9fcb-ae45f4c5bfeb',
content: '<p>This is a third discussion without replies.</p>',
votingRole: SystemIntakeGRBReviewerVotingRole.VOTING,
grbRole: SystemIntakeGRBReviewerRole.QIO_REP,
createdByUserAccount: {
__typename: 'UserAccount',
id: 'a9628365-16a5-49bf-9acc-7dbdade7288f',
commonName: users[3].commonName
},
systemIntakeID,
createdAt: '2024-11-17T9:00:00.368862Z'
},
replies: []
},
{
__typename: 'SystemIntakeGRBReviewDiscussion',
initialPost: {
__typename: 'SystemIntakeGRBReviewDiscussionPost',
id: 'df00daf2-f666-4014-98d3-fd28630fe996',
content:
'<p>This discussion without replies should not show up until list is expanded.</p>',
votingRole: SystemIntakeGRBReviewerVotingRole.ALTERNATE,
grbRole: SystemIntakeGRBReviewerRole.FED_ADMIN_BDG_CHAIR,
createdByUserAccount: {
__typename: 'UserAccount',
id: 'c7eefa37-b917-4fa3-8fc0-b86fa5de7df2',
commonName: users[8].commonName
},
systemIntakeID,
createdAt: '2024-11-17T9:30:00.368862Z'
},
replies: []
}
];
11 changes: 11 additions & 0 deletions src/gql/apolloGQL/grbReview/CreateSystemIntakeGRBDiscussionPost.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { gql } from '@apollo/client';

export default gql(/* GraphQL */ `
mutation CreateSystemIntakeGRBDiscussionPost(
$input: createSystemIntakeGRBDiscussionPostInput!
) {
createSystemIntakeGRBDiscussionPost(input: $input) {
id
}
}
`);
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { gql } from '@apollo/client';

export default gql(/* GraphQL */ `
mutation CreateSystemIntakeGRBDiscussionReply(
$input: createSystemIntakeGRBDiscussionReplyInput!
) {
createSystemIntakeGRBDiscussionReply(input: $input) {
id
}
}
`);
Loading

0 comments on commit 820a81d

Please sign in to comment.