[WEB-496] fix: issue comment (#3796)

* fix: issue comment empty string and on enter functionality

* fix: empty html tag validation added

* fix: purifying dom contents before saving comments

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
This commit is contained in:
Anmol Singh Bhatia
2024-02-26 16:11:35 +05:30
committed by GitHub
parent e1f13af084
commit 5c089f0223
4 changed files with 45 additions and 19 deletions

View File

@@ -11,6 +11,8 @@ import { TIssueComment } from "@plane/types";
// icons
import { Globe2, Lock } from "lucide-react";
import { useMention, useWorkspace } from "hooks/store";
// helpers
import { isEmptyHtmlString } from "helpers/string.helper";
const fileService = new FileService();
@@ -51,10 +53,10 @@ export const IssueCommentCreate: FC<TIssueCommentCreate> = (props) => {
const {
handleSubmit,
control,
watch,
formState: { isSubmitting },
reset,
watch,
} = useForm<Partial<TIssueComment>>({ defaultValues: { comment_html: "" } });
} = useForm<Partial<TIssueComment>>({ defaultValues: { comment_html: "<p></p>" } });
const onSubmit = async (formData: Partial<TIssueComment>) => {
await activityOperations.createComment(formData).finally(() => {
@@ -63,14 +65,19 @@ export const IssueCommentCreate: FC<TIssueCommentCreate> = (props) => {
});
};
const isEmpty =
watch("comment_html") === "" ||
watch("comment_html")?.trim() === "" ||
watch("comment_html") === "<p></p>" ||
isEmptyHtmlString(watch("comment_html") ?? "");
return (
<div
// onKeyDown={(e) => {
// if (e.key === "Enter" && !e.shiftKey) {
// e.preventDefault();
// // handleSubmit(onSubmit)(e);
// }
// }}
onKeyDown={(e) => {
if (e.key === "Enter" && !e.shiftKey && !isEmpty) {
handleSubmit(onSubmit)(e);
}
}}
>
<Controller
name="access"
@@ -81,15 +88,12 @@ export const IssueCommentCreate: FC<TIssueCommentCreate> = (props) => {
control={control}
render={({ field: { value, onChange } }) => (
<LiteTextEditorWithRef
onEnterKeyPress={(e) => {
handleSubmit(onSubmit)(e);
}}
cancelUploadImage={fileService.cancelUpload}
uploadFile={fileService.getUploadFileFunction(workspaceSlug as string)}
deleteFile={fileService.getDeleteImageFunction(workspaceId)}
restoreFile={fileService.getRestoreImageFunction(workspaceId)}
ref={editorRef}
value={value ?? ""}
value={!value ? "<p></p>" : value}
customClassName="p-2"
editorContentCustomClassNames="min-h-[35px]"
debouncedUpdatesEnabled={false}
@@ -105,7 +109,7 @@ export const IssueCommentCreate: FC<TIssueCommentCreate> = (props) => {
}
submitButton={
<Button
disabled={isSubmitting || watch("comment_html") === ""}
disabled={isSubmitting || isEmpty}
variant="primary"
type="submit"
className="!px-2.5 !py-1.5 !text-xs"

View File

@@ -4,6 +4,7 @@ import {
PROJECT_ISSUES_LIST_WITH_PARAMS,
VIEW_ISSUES,
} from "constants/fetch-keys";
import * as DOMPurify from 'dompurify';
export const addSpaceIfCamelCase = (str: string) => {
if (str === undefined || str === null) return "";
@@ -171,10 +172,10 @@ export const getFetchKeysForIssueMutation = (options: {
const ganttFetchKey = cycleId
? { ganttFetchKey: CYCLE_ISSUES_WITH_PARAMS(cycleId.toString(), ganttParams) }
: moduleId
? { ganttFetchKey: MODULE_ISSUES_WITH_PARAMS(moduleId.toString(), ganttParams) }
: viewId
? { ganttFetchKey: VIEW_ISSUES(viewId.toString(), viewGanttParams) }
: { ganttFetchKey: PROJECT_ISSUES_LIST_WITH_PARAMS(projectId?.toString() ?? "", ganttParams) };
? { ganttFetchKey: MODULE_ISSUES_WITH_PARAMS(moduleId.toString(), ganttParams) }
: viewId
? { ganttFetchKey: VIEW_ISSUES(viewId.toString(), viewGanttParams) }
: { ganttFetchKey: PROJECT_ISSUES_LIST_WITH_PARAMS(projectId?.toString() ?? "", ganttParams) };
return {
...ganttFetchKey,
@@ -224,3 +225,10 @@ export const checkEmailValidity = (email: string): boolean => {
return isEmailValid;
};
export const isEmptyHtmlString = (htmlString: string) => {
// Remove HTML tags using regex
const cleanText = DOMPurify.sanitize(htmlString, { ALLOWED_TAGS: [] });
// Trim the string and check if it's empty
return cleanText.trim() === "";
};

View File

@@ -34,6 +34,7 @@
"clsx": "^2.0.0",
"cmdk": "^0.2.0",
"date-fns": "^2.30.0",
"dompurify": "^3.0.9",
"dotenv": "^16.0.3",
"js-cookie": "^3.0.1",
"lodash": "^4.17.21",
@@ -61,6 +62,7 @@
"uuid": "^9.0.0"
},
"devDependencies": {
"@types/dompurify": "^3.0.5",
"@types/js-cookie": "^3.0.2",
"@types/lodash": "^4.14.202",
"@types/node": "18.0.6",