forked from github/plane
Fix/mentions spaces fix (#2667)
* feat: add mentions store to the space project * fix: added mentions highlights in read only comment cards * feat: added mention highlights in richtexteditor in space app
This commit is contained in:
parent
13389d1b2b
commit
6eb0bf4785
@ -8,6 +8,7 @@ interface IRichTextReadOnlyEditor {
|
||||
noBorder?: boolean;
|
||||
borderOnFocus?: boolean;
|
||||
customClassName?: string;
|
||||
mentionHighlights?: string[];
|
||||
}
|
||||
|
||||
interface RichTextReadOnlyEditorProps extends IRichTextReadOnlyEditor {
|
||||
@ -26,10 +27,12 @@ const RichReadOnlyEditor = ({
|
||||
customClassName,
|
||||
value,
|
||||
forwardedRef,
|
||||
mentionHighlights,
|
||||
}: RichTextReadOnlyEditorProps) => {
|
||||
const editor = useReadOnlyEditor({
|
||||
value,
|
||||
forwardedRef,
|
||||
mentionHighlights,
|
||||
});
|
||||
|
||||
const editorClassNames = getEditorClassNames({ noBorder, borderOnFocus, customClassName });
|
||||
|
@ -15,6 +15,7 @@ import { timeAgo } from "helpers/date-time.helper";
|
||||
import { Comment } from "types/issue";
|
||||
// services
|
||||
import fileService from "services/file.service";
|
||||
import useEditorSuggestions from "hooks/use-editor-suggestions";
|
||||
|
||||
type Props = {
|
||||
workspaceSlug: string;
|
||||
@ -28,6 +29,8 @@ export const CommentCard: React.FC<Props> = observer((props) => {
|
||||
// states
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
|
||||
const mentionsConfig = useEditorSuggestions();
|
||||
|
||||
const editorRef = React.useRef<any>(null);
|
||||
|
||||
const showEditorRef = React.useRef<any>(null);
|
||||
@ -135,7 +138,7 @@ export const CommentCard: React.FC<Props> = observer((props) => {
|
||||
ref={showEditorRef}
|
||||
value={comment.comment_html}
|
||||
customClassName="text-xs border border-custom-border-200 bg-custom-background-100"
|
||||
mentionHighlights={userStore.currentUser?.id ? [userStore.currentUser?.id] : []}
|
||||
mentionHighlights={mentionsConfig.mentionHighlights}
|
||||
/>
|
||||
<CommentReactions commentId={comment.id} projectId={comment.project} />
|
||||
</div>
|
||||
|
@ -2,27 +2,33 @@ import { IssueReactions } from "components/issues/peek-overview";
|
||||
import { RichReadOnlyEditor } from "@plane/rich-text-editor";
|
||||
// types
|
||||
import { IIssue } from "types/issue";
|
||||
import useEditorSuggestions from "hooks/use-editor-suggestions";
|
||||
|
||||
type Props = {
|
||||
issueDetails: IIssue;
|
||||
};
|
||||
|
||||
export const PeekOverviewIssueDetails: React.FC<Props> = ({ issueDetails }) => (
|
||||
<div className="space-y-2">
|
||||
<h6 className="font-medium text-custom-text-200">
|
||||
{issueDetails.project_detail.identifier}-{issueDetails.sequence_id}
|
||||
</h6>
|
||||
<h4 className="break-words text-2xl font-semibold">{issueDetails.name}</h4>
|
||||
{issueDetails.description_html !== "" && issueDetails.description_html !== "<p></p>" && (
|
||||
<RichReadOnlyEditor
|
||||
value={!issueDetails.description_html ||
|
||||
issueDetails.description_html === "" ||
|
||||
(typeof issueDetails.description_html === "object" &&
|
||||
Object.keys(issueDetails.description_html).length === 0)
|
||||
? "<p></p>"
|
||||
: issueDetails.description_html}
|
||||
customClassName="p-3 min-h-[50px] shadow-sm" />
|
||||
)}
|
||||
<IssueReactions />
|
||||
</div>
|
||||
);
|
||||
export const PeekOverviewIssueDetails: React.FC<Props> = ({ issueDetails }) => {
|
||||
|
||||
const mentionConfig = useEditorSuggestions();
|
||||
|
||||
return (
|
||||
<div className="space-y-2">
|
||||
<h6 className="font-medium text-custom-text-200">
|
||||
{issueDetails.project_detail.identifier}-{issueDetails.sequence_id}
|
||||
</h6>
|
||||
<h4 className="break-words text-2xl font-semibold">{issueDetails.name}</h4>
|
||||
{issueDetails.description_html !== "" && issueDetails.description_html !== "<p></p>" && (
|
||||
<RichReadOnlyEditor
|
||||
value={!issueDetails.description_html ||
|
||||
issueDetails.description_html === "" ||
|
||||
(typeof issueDetails.description_html === "object" &&
|
||||
Object.keys(issueDetails.description_html).length === 0)
|
||||
? "<p></p>"
|
||||
: issueDetails.description_html}
|
||||
customClassName="p-3 min-h-[50px] shadow-sm" mentionHighlights={mentionConfig.mentionHighlights} />
|
||||
)}
|
||||
<IssueReactions />
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
13
space/hooks/use-editor-suggestions.tsx
Normal file
13
space/hooks/use-editor-suggestions.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import { useMobxStore } from "lib/mobx/store-provider";
|
||||
import { RootStore } from "store/root";
|
||||
|
||||
const useEditorSuggestions = () => {
|
||||
const { mentionsStore }: RootStore = useMobxStore();
|
||||
|
||||
return {
|
||||
// mentionSuggestions: mentionsStore.mentionSuggestions,
|
||||
mentionHighlights: mentionsStore.mentionHighlights,
|
||||
};
|
||||
};
|
||||
|
||||
export default useEditorSuggestions;
|
45
space/store/mentions.store.ts
Normal file
45
space/store/mentions.store.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { IMentionHighlight } from "@plane/lite-text-editor";
|
||||
import { RootStore } from "./root";
|
||||
import { computed, makeObservable } from "mobx";
|
||||
|
||||
export interface IMentionsStore {
|
||||
// mentionSuggestions: IMentionSuggestion[];
|
||||
mentionHighlights: IMentionHighlight[];
|
||||
}
|
||||
|
||||
export class MentionsStore implements IMentionsStore{
|
||||
|
||||
// root store
|
||||
rootStore;
|
||||
|
||||
constructor(_rootStore: RootStore ){
|
||||
|
||||
// rootStore
|
||||
this.rootStore = _rootStore;
|
||||
|
||||
makeObservable(this, {
|
||||
mentionHighlights: computed,
|
||||
// mentionSuggestions: computed
|
||||
})
|
||||
}
|
||||
|
||||
// get mentionSuggestions() {
|
||||
// const projectMembers = this.rootStore.project.project.
|
||||
|
||||
// const suggestions = projectMembers === null ? [] : projectMembers.map((member) => ({
|
||||
// id: member.member.id,
|
||||
// type: "User",
|
||||
// title: member.member.display_name,
|
||||
// subtitle: member.member.email ?? "",
|
||||
// avatar: member.member.avatar,
|
||||
// redirect_uri: `/${member.workspace.slug}/profile/${member.member.id}`,
|
||||
// }))
|
||||
|
||||
// return suggestions
|
||||
// }
|
||||
|
||||
get mentionHighlights() {
|
||||
const user = this.rootStore.user.currentUser;
|
||||
return user ? [user.id] : []
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import UserStore from "./user";
|
||||
import IssueStore, { IIssueStore } from "./issue";
|
||||
import ProjectStore, { IProjectStore } from "./project";
|
||||
import IssueDetailStore, { IIssueDetailStore } from "./issue_details";
|
||||
import { IMentionsStore, MentionsStore } from "./mentions.store";
|
||||
|
||||
enableStaticRendering(typeof window === "undefined");
|
||||
|
||||
@ -13,11 +14,13 @@ export class RootStore {
|
||||
issue: IIssueStore;
|
||||
issueDetails: IIssueDetailStore;
|
||||
project: IProjectStore;
|
||||
mentionsStore: IMentionsStore;
|
||||
|
||||
constructor() {
|
||||
this.user = new UserStore(this);
|
||||
this.issue = new IssueStore(this);
|
||||
this.project = new ProjectStore(this);
|
||||
this.issueDetails = new IssueDetailStore(this);
|
||||
this.mentionsStore = new MentionsStore(this);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user