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
129 changes: 129 additions & 0 deletions web/components/web-view/add-comment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import React from "react";

// next
import { useRouter } from "next/router";

// react-hook-form
import { useForm, Controller } from "react-hook-form";

// hooks
import useProjectDetails from "hooks/use-project-details";

// components
import { TipTapEditor } from "components/tiptap";

// icons
import { Send } from "lucide-react";

// ui
import { Icon, SecondaryButton, Tooltip, PrimaryButton } from "components/ui";

// types
import type { IIssueComment } from "types";

const defaultValues: Partial<IIssueComment> = {
access: "INTERNAL",
comment_html: "",
};

type Props = {
disabled?: boolean;
onSubmit: (data: IIssueComment) => Promise<void>;
};

const commentAccess = [
{
icon: "lock",
key: "INTERNAL",
label: "Private",
},
{
icon: "public",
key: "EXTERNAL",
label: "Public",
},
];

export const AddComment: React.FC<Props> = ({ disabled = false, onSubmit }) => {
const editorRef = React.useRef<any>(null);

const router = useRouter();
const { workspaceSlug } = router.query;

const { projectDetails } = useProjectDetails();

const showAccessSpecifier = projectDetails?.is_deployed;

const {
control,
formState: { isSubmitting },
handleSubmit,
reset,
} = useForm<IIssueComment>({ defaultValues });

const handleAddComment = async (formData: IIssueComment) => {
if (!formData.comment_html || isSubmitting) return;

await onSubmit(formData).then(() => {
reset(defaultValues);
editorRef.current?.clearEditor();
});
};

return (
<form className="w-full flex gap-x-2" onSubmit={handleSubmit(handleAddComment)}>
<div className="relative flex-grow">
{showAccessSpecifier && (
<div className="absolute bottom-2 left-3 z-[1]">
<Controller
control={control}
name="access"
render={({ field: { onChange, value } }) => (
<div className="flex border border-custom-border-300 divide-x divide-custom-border-300 rounded overflow-hidden">
{commentAccess.map((access) => (
<Tooltip key={access.key} tooltipContent={access.label}>
<button
type="button"
onClick={() => onChange(access.key)}
className={`grid place-items-center p-1 hover:bg-custom-background-80 ${
value === access.key ? "bg-custom-background-80" : ""
}`}
>
<Icon
iconName={access.icon}
className={`w-4 h-4 -mt-1 ${
value === access.key ? "!text-custom-text-100" : "!text-custom-text-400"
}`}
/>
</button>
</Tooltip>
))}
</div>
)}
/>
</div>
)}
<Controller
name="comment_html"
control={control}
render={({ field: { value, onChange } }) => (
<TipTapEditor
workspaceSlug={workspaceSlug as string}
ref={editorRef}
value={!value || value === "" ? "<p></p>" : value}
customClassName="p-3 min-h-[100px] shadow-sm"
debouncedUpdatesEnabled={false}
onChange={(comment_json: Object, comment_html: string) => onChange(comment_html)}
/>
)}
/>
</div>

<div className="inline">
<PrimaryButton type="submit" disabled={isSubmitting || disabled} className="mt-2">
<Send className="w-4 h-4" />
</PrimaryButton>
</div>
</form>
);
};
36 changes: 25 additions & 11 deletions web/components/web-view/create-update-link-form.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// react
import React from "react";
import React, { useEffect } from "react";

// next
import { useRouter } from "next/router";
Expand All @@ -14,7 +14,7 @@ import { useForm } from "react-hook-form";
import issuesService from "services/issues.service";

// fetch keys
import { M_ISSUE_DETAILS } from "constants/fetch-keys";
import { ISSUE_DETAILS } from "constants/fetch-keys";

// hooks
import useToast from "hooks/use-toast";
Expand All @@ -26,13 +26,14 @@ import { PrimaryButton, Input } from "components/ui";
import type { linkDetails, IIssueLink } from "types";

type Props = {
links?: linkDetails[];
isOpen: boolean;
data?: linkDetails;
links?: linkDetails[];
onSuccess: () => void;
};

export const CreateUpdateLinkForm: React.FC<Props> = (props) => {
const { data, links, onSuccess } = props;
const { isOpen, data, links, onSuccess } = props;

const router = useRouter();
const { workspaceSlug, projectId, issueId } = router.query;
Expand All @@ -42,6 +43,7 @@ export const CreateUpdateLinkForm: React.FC<Props> = (props) => {
const {
register,
handleSubmit,
reset,
formState: { errors, isSubmitting },
} = useForm({
defaultValues: {
Expand All @@ -50,6 +52,22 @@ export const CreateUpdateLinkForm: React.FC<Props> = (props) => {
},
});

useEffect(() => {
if (!data) return;
reset({
title: data.title,
url: data.url,
});
}, [data, reset]);

useEffect(() => {
if (!isOpen)
reset({
title: "",
url: "",
});
}, [isOpen, reset]);

const onSubmit = async (formData: IIssueLink) => {
if (!workspaceSlug || !projectId || !issueId) return;

Expand All @@ -65,9 +83,7 @@ export const CreateUpdateLinkForm: React.FC<Props> = (props) => {
)
.then(() => {
onSuccess();
mutate(
M_ISSUE_DETAILS(workspaceSlug.toString(), projectId.toString(), issueId.toString())
);
mutate(ISSUE_DETAILS(issueId.toString()));
})
.catch((err) => {
if (err?.status === 400)
Expand Down Expand Up @@ -95,7 +111,7 @@ export const CreateUpdateLinkForm: React.FC<Props> = (props) => {
);

mutate(
M_ISSUE_DETAILS(workspaceSlug.toString(), projectId.toString(), issueId.toString()),
ISSUE_DETAILS(issueId.toString()),
(prevData) => ({ ...prevData, issue_link: updatedLinks }),
false
);
Expand All @@ -110,9 +126,7 @@ export const CreateUpdateLinkForm: React.FC<Props> = (props) => {
)
.then(() => {
onSuccess();
mutate(
M_ISSUE_DETAILS(workspaceSlug.toString(), projectId.toString(), issueId.toString())
);
mutate(ISSUE_DETAILS(issueId.toString()));
});
}
};
Expand Down
4 changes: 4 additions & 0 deletions web/components/web-view/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ export * from "./issue-attachments";
export * from "./issue-properties-detail";
export * from "./issue-link-list";
export * from "./create-update-link-form";
export * from "./issue-activity";
export * from "./select-assignee";
export * from "./select-estimate";
export * from "./add-comment";
Loading