diff --git a/apps/app/components/core/gpt-assistant-modal.tsx b/apps/app/components/core/gpt-assistant-modal.tsx index 0afe481a7..e9c7241c1 100644 --- a/apps/app/components/core/gpt-assistant-modal.tsx +++ b/apps/app/components/core/gpt-assistant-modal.tsx @@ -1,6 +1,7 @@ import { useEffect, useState } from "react"; import { useRouter } from "next/router"; +import dynamic from "next/dynamic"; // react-hook-form import { useForm } from "react-hook-form"; @@ -16,6 +17,7 @@ type Props = { handleClose: () => void; inset?: string; content: string; + htmlContent?: string; onResponse: (response: string) => void; }; @@ -24,11 +26,16 @@ type FormData = { task: string; }; +const RemirrorRichTextEditor = dynamic(() => import("components/rich-text-editor"), { + ssr: false, +}); + export const GptAssistantModal: React.FC = ({ isOpen, handleClose, inset = "top-0 left-0", content, + htmlContent, onResponse, }) => { const [response, setResponse] = useState(""); @@ -62,15 +69,6 @@ export const GptAssistantModal: React.FC = ({ const handleResponse = async (formData: FormData) => { if (!workspaceSlug || !projectId) return; - if (!content || content === "") { - setToastAlert({ - type: "error", - title: "Error!", - message: "Please enter some description to get AI assistance.", - }); - return; - } - if (formData.task === "") { setToastAlert({ type: "error", @@ -82,11 +80,11 @@ export const GptAssistantModal: React.FC = ({ await aiService .createGptTask(workspaceSlug as string, projectId as string, { - prompt: content, + prompt: content && content !== "" ? content : "", task: formData.task, }) .then((res) => { - setResponse(res.response); + setResponse(res.response_html); setFocus("task"); if (res.response === "") setInvalidResponse(true); @@ -105,12 +103,28 @@ export const GptAssistantModal: React.FC = ({ }`} >
-
- Content:

{content}

-
+ {content && content !== "" && ( +
+ Content: + {content}

} + customClassName="-mx-3 -my-3" + noBorder + borderOnFocus={false} + editable={false} + /> +
+ )} {response !== "" && (
- Response:

{response}

+ Response: + ${response}

`} + customClassName="-mx-3 -my-3" + noBorder + borderOnFocus={false} + editable={false} + />
)} {invalidResponse && ( @@ -123,7 +137,11 @@ export const GptAssistantModal: React.FC = ({ type="text" name="task" register={register} - placeholder="Tell OpenAI what action to perform on this content..." + placeholder={`${ + content && content !== "" + ? "Tell AI what action to perform on this content..." + : "Ask AI anything..." + }`} autoComplete="off" />
diff --git a/apps/app/components/issues/form.tsx b/apps/app/components/issues/form.tsx index d111ae6fb..81e01e6be 100644 --- a/apps/app/components/issues/form.tsx +++ b/apps/app/components/issues/form.tsx @@ -239,7 +239,11 @@ export const IssueForm: FC = ({ control={control} render={({ field: { value } }) => ( setValue("description", jsonValue)} onHTMLChange={(htmlValue) => setValue("description_html", htmlValue)} placeholder="Description" diff --git a/apps/app/components/pages/create-update-page-modal.tsx b/apps/app/components/pages/create-update-page-modal.tsx index 18b2c9b34..ed12f8f46 100644 --- a/apps/app/components/pages/create-update-page-modal.tsx +++ b/apps/app/components/pages/create-update-page-modal.tsx @@ -45,12 +45,20 @@ export const CreateUpdatePageModal: React.FC = ({ isOpen, handleClose, da mutate(RECENT_PAGES_LIST(projectId as string)); mutate( MY_PAGES_LIST(projectId as string), - (prevData) => [res, ...(prevData as IPage[])], + (prevData) => { + if (!prevData) return undefined; + + return [res, ...(prevData as IPage[])]; + }, false ); mutate( ALL_PAGES_LIST(projectId as string), - (prevData) => [res, ...(prevData as IPage[])], + (prevData) => { + if (!prevData) return undefined; + + return [res, ...(prevData as IPage[])]; + }, false ); onClose(); diff --git a/apps/app/components/pages/delete-page-modal.tsx b/apps/app/components/pages/delete-page-modal.tsx index 38dff3264..94468f2b8 100644 --- a/apps/app/components/pages/delete-page-modal.tsx +++ b/apps/app/components/pages/delete-page-modal.tsx @@ -2,6 +2,8 @@ import React, { useState } from "react"; import { useRouter } from "next/router"; +import { mutate } from "swr"; + // headless ui import { Dialog, Transition } from "@headlessui/react"; // services @@ -14,6 +16,13 @@ import { DangerButton, SecondaryButton } from "components/ui"; import { ExclamationTriangleIcon } from "@heroicons/react/24/outline"; // types import type { IPage } from "types"; +// fetch-keys +import { + ALL_PAGES_LIST, + FAVORITE_PAGES_LIST, + MY_PAGES_LIST, + RECENT_PAGES_LIST, +} from "constants/fetch-keys"; type TConfirmPageDeletionProps = { isOpen: boolean; @@ -45,6 +54,22 @@ export const DeletePageModal: React.FC = ({ await pagesService .deletePage(workspaceSlug as string, data.project, data.id) .then(() => { + mutate(RECENT_PAGES_LIST(projectId as string)); + mutate( + MY_PAGES_LIST(projectId as string), + (prevData) => (prevData ?? []).filter((page) => page.id !== data?.id), + false + ); + mutate( + ALL_PAGES_LIST(projectId as string), + (prevData) => (prevData ?? []).filter((page) => page.id !== data?.id), + false + ); + mutate( + FAVORITE_PAGES_LIST(projectId as string), + (prevData) => (prevData ?? []).filter((page) => page.id !== data?.id), + false + ); handleClose(); setToastAlert({ type: "success", diff --git a/apps/app/components/pages/pages-view.tsx b/apps/app/components/pages/pages-view.tsx index dc4e0d19c..e8b483016 100644 --- a/apps/app/components/pages/pages-view.tsx +++ b/apps/app/components/pages/pages-view.tsx @@ -57,7 +57,6 @@ export const PagesView: React.FC = ({ pages, viewType }) => { const handleAddToFavorites = (page: IPage) => { if (!workspaceSlug || !projectId) return; - mutate(RECENT_PAGES_LIST(projectId as string)); mutate( ALL_PAGES_LIST(projectId as string), (prevData) => @@ -89,6 +88,7 @@ export const PagesView: React.FC = ({ pages, viewType }) => { page: page.id, }) .then(() => { + mutate(RECENT_PAGES_LIST(projectId as string)); setToastAlert({ type: "success", title: "Success!", @@ -107,7 +107,6 @@ export const PagesView: React.FC = ({ pages, viewType }) => { const handleRemoveFromFavorites = (page: IPage) => { if (!workspaceSlug || !projectId) return; - mutate(RECENT_PAGES_LIST(projectId as string)); mutate( ALL_PAGES_LIST(projectId as string), (prevData) => @@ -137,6 +136,7 @@ export const PagesView: React.FC = ({ pages, viewType }) => { pagesService .removePageFromFavorites(workspaceSlug as string, projectId as string, page.id) .then(() => { + mutate(RECENT_PAGES_LIST(projectId as string)); setToastAlert({ type: "success", title: "Success!", diff --git a/apps/app/components/pages/single-page-block.tsx b/apps/app/components/pages/single-page-block.tsx index 1aa914022..8c9064ad7 100644 --- a/apps/app/components/pages/single-page-block.tsx +++ b/apps/app/components/pages/single-page-block.tsx @@ -17,11 +17,16 @@ import useToast from "hooks/use-toast"; import { CreateUpdateIssueModal } from "components/issues"; import { GptAssistantModal } from "components/core"; // ui -import { CustomMenu, Loader, TextArea } from "components/ui"; +import { CustomMenu, Input, Loader, TextArea } from "components/ui"; // icons -import { LayerDiagonalIcon, WaterDropIcon } from "components/icons"; +import { LayerDiagonalIcon } from "components/icons"; import { ArrowPathIcon } from "@heroicons/react/20/solid"; -import { CheckIcon } from "@heroicons/react/24/outline"; +import { + BoltIcon, + CheckIcon, + CursorArrowRaysIcon, + SparklesIcon, +} from "@heroicons/react/24/outline"; // helpers import { copyTextToClipboard } from "helpers/string.helper"; // types @@ -163,21 +168,8 @@ export const SinglePageBlock: React.FC = ({ block, projectDetails }) => { const handleAiAssistance = async (response: string) => { if (!workspaceSlug || !projectId) return; - setValue("description", { - type: "doc", - content: [ - { - type: "paragraph", - content: [ - { - text: response, - type: "text", - }, - ], - }, - ], - }); - setValue("description_html", `

${response}

`); + setValue("description", {}); + setValue("description_html", `${watch("description_html")}

${response}

`); handleSubmit(updatePageBlock)() .then(() => { setToastAlert({ @@ -253,7 +245,7 @@ export const SinglePageBlock: React.FC = ({ block, projectDetails }) => { }} />
-