diff --git a/packages/editor/core/src/hooks/use-editor.tsx b/packages/editor/core/src/hooks/use-editor.tsx index 78d252c81..a90be65f1 100644 --- a/packages/editor/core/src/hooks/use-editor.tsx +++ b/packages/editor/core/src/hooks/use-editor.tsx @@ -34,7 +34,7 @@ interface CustomEditorProps { suggestions?: () => Promise; }; handleEditorReady?: (value: boolean) => void; - placeholder?: string | ((isFocused: boolean) => string); + placeholder?: string | ((isFocused: boolean, value: string) => string); tabIndex?: number; } diff --git a/packages/editor/core/src/ui/extensions/index.tsx b/packages/editor/core/src/ui/extensions/index.tsx index f4dbaee3b..f6afdfbc1 100644 --- a/packages/editor/core/src/ui/extensions/index.tsx +++ b/packages/editor/core/src/ui/extensions/index.tsx @@ -43,7 +43,7 @@ type TArguments = { cancelUploadImage?: () => void; uploadFile: UploadImage; }; - placeholder?: string | ((isFocused: boolean) => string); + placeholder?: string | ((isFocused: boolean, value: string) => string); tabIndex?: number; }; @@ -147,7 +147,7 @@ export const CoreEditorExtensions = ({ if (placeholder) { if (typeof placeholder === "string") return placeholder; - else return placeholder(editor.isFocused); + else return placeholder(editor.isFocused, editor.getHTML()); } return "Press '/' for commands..."; diff --git a/packages/editor/document-editor/src/ui/index.tsx b/packages/editor/document-editor/src/ui/index.tsx index 3c36ed11c..1f1c5f706 100644 --- a/packages/editor/document-editor/src/ui/index.tsx +++ b/packages/editor/document-editor/src/ui/index.tsx @@ -31,7 +31,7 @@ interface IDocumentEditor { suggestions: () => Promise; }; tabIndex?: number; - placeholder?: string | ((isFocused: boolean) => string); + placeholder?: string | ((isFocused: boolean, value: string) => string); } const DocumentEditor = (props: IDocumentEditor) => { diff --git a/packages/editor/lite-text-editor/src/ui/index.tsx b/packages/editor/lite-text-editor/src/ui/index.tsx index 71846eca7..fe9453110 100644 --- a/packages/editor/lite-text-editor/src/ui/index.tsx +++ b/packages/editor/lite-text-editor/src/ui/index.tsx @@ -32,7 +32,7 @@ export interface ILiteTextEditor { suggestions?: () => Promise; }; tabIndex?: number; - placeholder?: string | ((isFocused: boolean) => string); + placeholder?: string | ((isFocused: boolean, value: string) => string); } const LiteTextEditor = (props: ILiteTextEditor) => { diff --git a/packages/editor/rich-text-editor/src/ui/index.tsx b/packages/editor/rich-text-editor/src/ui/index.tsx index e82615b95..0cb32e543 100644 --- a/packages/editor/rich-text-editor/src/ui/index.tsx +++ b/packages/editor/rich-text-editor/src/ui/index.tsx @@ -35,7 +35,7 @@ export type IRichTextEditor = { highlights: () => Promise; suggestions: () => Promise; }; - placeholder?: string | ((isFocused: boolean) => string); + placeholder?: string | ((isFocused: boolean, value: string) => string); tabIndex?: number; }; diff --git a/web/components/inbox/modals/create-edit-modal/issue-description.tsx b/web/components/inbox/modals/create-edit-modal/issue-description.tsx index c749a6700..74c62f97c 100644 --- a/web/components/inbox/modals/create-edit-modal/issue-description.tsx +++ b/web/components/inbox/modals/create-edit-modal/issue-description.tsx @@ -5,6 +5,8 @@ import { TIssue } from "@plane/types"; import { Loader } from "@plane/ui"; // components import { RichTextEditor } from "@/components/editor/rich-text-editor/rich-text-editor"; +// helpers +import { getDescriptionPlaceholder } from "@/helpers/issue.helper"; // hooks import { useProjectInbox } from "@/hooks/store"; @@ -39,10 +41,7 @@ export const InboxIssueDescription: FC = observer((props projectId={projectId} dragDropEnabled={false} onChange={(_description: object, description_html: string) => handleData("description_html", description_html)} - placeholder={(isFocused) => { - if (isFocused) return "Press '/' for commands..."; - else return "Click to add description"; - }} + placeholder={getDescriptionPlaceholder} /> ); diff --git a/web/components/issues/description-input.tsx b/web/components/issues/description-input.tsx index aededa28f..b8cfbd582 100644 --- a/web/components/issues/description-input.tsx +++ b/web/components/issues/description-input.tsx @@ -9,6 +9,8 @@ import { Loader } from "@plane/ui"; // components import { RichTextEditor, RichTextReadOnlyEditor } from "@/components/editor"; import { TIssueOperations } from "@/components/issues/issue-detail"; +// helpers +import { getDescriptionPlaceholder } from "@/helpers/issue.helper"; // hooks import { useWorkspace } from "@/hooks/store"; @@ -19,7 +21,7 @@ export type IssueDescriptionInputProps = { initialValue: string | undefined; disabled?: boolean; issueOperations: TIssueOperations; - placeholder?: string | ((isFocused: boolean) => string); + placeholder?: string | ((isFocused: boolean, value: string) => string); setIsSubmitting: (initialValue: "submitting" | "submitted" | "saved") => void; swrIssueDescription: string | null | undefined; }; @@ -106,12 +108,7 @@ export const IssueDescriptionInput: FC = observer((p debouncedFormSave(); }} placeholder={ - placeholder - ? placeholder - : (isFocused) => { - if (isFocused) return "Press '/' for commands..."; - else return "Click to add description"; - } + placeholder ? placeholder : (isFocused, value) => getDescriptionPlaceholder(isFocused, value) } /> ) : ( diff --git a/web/components/issues/issue-modal/form.tsx b/web/components/issues/issue-modal/form.tsx index 2e426c9e8..43bfb90e5 100644 --- a/web/components/issues/issue-modal/form.tsx +++ b/web/components/issues/issue-modal/form.tsx @@ -23,7 +23,7 @@ import { ParentIssuesListModal } from "@/components/issues"; import { IssueLabelSelect } from "@/components/issues/select"; import { CreateLabelModal } from "@/components/labels"; import { renderFormattedPayloadDate, getDate } from "@/helpers/date-time.helper"; -import { getChangedIssuefields } from "@/helpers/issue.helper"; +import { getChangedIssuefields, getDescriptionPlaceholder } from "@/helpers/issue.helper"; import { shouldRenderProject } from "@/helpers/project.helper"; import { useApplication, useEstimate, useIssueDetail, useProject, useWorkspace } from "@/hooks/store"; import { useProjectIssueProperties } from "@/hooks/use-project-issue-properties"; @@ -473,17 +473,13 @@ export const IssueFormRoot: FC = observer((props) => { workspaceSlug={workspaceSlug?.toString() as string} workspaceId={workspaceId} projectId={projectId} - // dragDropEnabled={false} onChange={(_description: object, description_html: string) => { onChange(description_html); handleFormChange(); }} ref={editorRef} tabIndex={getTabIndex("description_html")} - placeholder={(isFocused) => { - if (isFocused) return "Press '/' for commands..."; - else return "Click to add description"; - }} + placeholder={getDescriptionPlaceholder} /> )} /> diff --git a/web/helpers/issue.helper.ts b/web/helpers/issue.helper.ts index 2ac7dc7bd..614994767 100644 --- a/web/helpers/issue.helper.ts +++ b/web/helpers/issue.helper.ts @@ -1,13 +1,6 @@ import differenceInCalendarDays from "date-fns/differenceInCalendarDays"; import { v4 as uuidv4 } from "uuid"; -// helpers -import { getDate } from "@/helpers/date-time.helper"; -import { orderArrayBy } from "@/helpers/array.helper"; // types -import { IGanttBlock } from "@/components/gantt-chart"; -// constants -import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; -import { STATE_GROUPS } from "@/constants/state"; import { TIssue, TIssueGroupByOptions, @@ -16,6 +9,13 @@ import { TIssueParams, TStateGroups, } from "@plane/types"; +import { IGanttBlock } from "@/components/gantt-chart"; +// constants +import { ISSUE_DISPLAY_FILTERS_BY_LAYOUT } from "@/constants/issue"; +import { STATE_GROUPS } from "@/constants/state"; +// helpers +import { orderArrayBy } from "@/helpers/array.helper"; +import { getDate } from "@/helpers/date-time.helper"; type THandleIssuesMutation = ( formData: Partial, @@ -205,3 +205,9 @@ export const formatTextList = (TextArray: string[]): string => { return `${TextArray.slice(0, 3).join(", ")}, and +${count - 3} more`; } }; + +export const getDescriptionPlaceholder = (isFocused: boolean, description: string | undefined): string => { + const isDescriptionEmpty = !description || description === "

" || description.trim() === ""; + if (!isDescriptionEmpty || isFocused) return "Press '/' for commands..."; + else return "Click to add description"; +};