Fix: Restore Issue Embeds in Place of Placeholder Components (#92)

* restore: use issue embed hook restored

* chore: implemented useIssueEmbed hook in pages for embed props

* fix: passed issue embed config to document editor

* fix: restored issue embed extension in place of placeholder
This commit is contained in:
Henit Chobisa
2024-01-25 00:54:19 +05:30
committed by GitHub
parent 56f7ed50c1
commit 3f5e3eb2fe
6 changed files with 75 additions and 7 deletions

View File

@@ -76,7 +76,7 @@ export const EditorHeader = (props: IEditorHeader) => {
/>
)}
{!isLocked && !isArchived ? (
{!isLocked && !isArchived && !readonly ? (
<div
className={`absolute right-[120px] flex items-center gap-x-2 transition-all duration-300 ${
isSubmitting === "saved" ? "fadeOut" : "fadeIn"

View File

@@ -2,8 +2,6 @@ import { IssueWidget } from "src/ui/extensions/widgets/issue-embed-widget/issue-
import { IIssueEmbedConfig } from "src/ui/extensions/widgets/issue-embed-widget/types";
export * from "./issue-widget-card";
export const IssueWidgetPlaceholder = () => IssueWidget.configure({});
interface IssueWidgetExtensionProps {
issueEmbedConfig?: IIssueEmbedConfig;
}

View File

@@ -34,7 +34,9 @@ export const IssueWidget = Node.create({
},
addNodeView() {
return ReactNodeViewRenderer((props: Object) => <IssueWidgetCard {...props} />);
return ReactNodeViewRenderer((props: Object) => (
<IssueWidgetCard {...props} issueEmbedConfig={this.options.issueEmbedConfig} />
));
},
parseHTML() {

View File

@@ -8,7 +8,8 @@ import { useEditorMarkings } from "src/hooks/use-editor-markings";
import { DocumentDetails } from "src/types/editor-types";
import { IPageArchiveConfig, IPageLockConfig, IDuplicationConfig } from "src/types/menu-actions";
import { getMenuOptions } from "src/utils/menu-options";
import { IssueWidgetPlaceholder } from "../extensions/widgets/issue-embed-widget";
import { IssueWidgetExtension } from "../extensions/widgets/issue-embed-widget";
import { IEmbedConfig } from "../extensions/widgets/issue-embed-widget/types";
interface IDocumentReadOnlyEditor {
value: string;
@@ -28,6 +29,7 @@ interface IDocumentReadOnlyEditor {
message: string;
type: "success" | "error" | "warning" | "info";
}) => void;
embedConfig?: IEmbedConfig;
}
interface DocumentReadOnlyEditorProps extends IDocumentReadOnlyEditor {
@@ -43,6 +45,7 @@ const DocumentReadOnlyEditor = ({
noBorder,
borderOnFocus,
customClassName,
embedConfig,
value,
documentDetails,
forwardedRef,
@@ -60,7 +63,7 @@ const DocumentReadOnlyEditor = ({
value,
forwardedRef,
rerenderOnPropsChange,
extensions: [IssueWidgetPlaceholder()],
extensions: [IssueWidgetExtension({ issueEmbedConfig: embedConfig?.issueEmbedConfig })],
});
useEffect(() => {

View File

@@ -0,0 +1,47 @@
import { PROJECT_ISSUES_LIST } from "constants/fetch-keys";
import { StoreContext } from "contexts/store-context";
import { toJS } from "mobx";
import { useContext } from "react";
import { IssueService } from "services/issue";
import useSWR from "swr";
import { useIssueDetail, useMember, useProject, useProjectState } from "./store";
const issueService = new IssueService();
export const useIssueEmbeds = () => {
const workspaceSlug = useContext(StoreContext).app.router.workspaceSlug;
const projectId = useContext(StoreContext).app.router.projectId;
const { getProjectById } = useProject();
const { setPeekIssue } = useIssueDetail();
const { getStateById } = useProjectState();
const { getUserDetails } = useMember();
const { data: issuesResponse, isLoading: issuesLoading } = useSWR(
workspaceSlug && projectId ? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string) : null,
workspaceSlug && projectId ? () => issueService.getIssues(workspaceSlug as string, projectId as string) : null
);
const issues = Object.values(issuesResponse ?? {});
const issuesWithStateAndProject = issues.map((issue) => ({
...issue,
state_detail: toJS(getStateById(issue.state_id)),
project_detail: toJS(getProjectById(issue.project_id)),
assignee_details: issue.assignee_ids.map((assigneeid) => toJS(getUserDetails(assigneeid))),
}));
const fetchIssue = (issueId: string) => issuesWithStateAndProject.find((issue) => issue.id === issueId);
const issueWidgetClickAction = (issueId: string) => {
if (!workspaceSlug || !projectId) return;
setPeekIssue({ workspaceSlug, projectId: projectId, issueId });
};
return {
issues: issuesWithStateAndProject,
issuesLoading,
fetchIssue,
issueWidgetClickAction,
};
};

View File

@@ -18,6 +18,8 @@ import { PageDetailsHeader } from "components/headers/page-details";
// ui
import { DocumentEditorWithRef, DocumentReadOnlyEditorWithRef } from "@plane/document-editor";
import { Spinner } from "@plane/ui";
// hooks
import { useIssueEmbeds } from "hooks/use-issue-embeds";
// assets
// helpers
// types
@@ -62,6 +64,8 @@ const PageDetailsPage: NextPageWithLayout = observer(() => {
defaultValues: { name: "", description_html: "" },
});
const { issues, fetchIssue, issueWidgetClickAction, issuesLoading } = useIssueEmbeds();
const {
archivePage: archivePageAction,
restorePage: restorePageAction,
@@ -255,7 +259,7 @@ const PageDetailsPage: NextPageWithLayout = observer(() => {
const userCanLock =
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
return pageIdMobx ? (
return pageIdMobx && issues && !issuesLoading ? (
<div className="flex h-full flex-col justify-between">
<div className="h-full w-full overflow-hidden">
{isPageReadOnly ? (
@@ -284,6 +288,13 @@ const PageDetailsPage: NextPageWithLayout = observer(() => {
}
: undefined
}
embedConfig={{
issueEmbedConfig: {
issues: issues,
fetchIssue: fetchIssue,
clickAction: issueWidgetClickAction,
},
}}
/>
) : (
<div className="relative h-full w-full overflow-hidden">
@@ -327,6 +338,13 @@ const PageDetailsPage: NextPageWithLayout = observer(() => {
: undefined
}
pageLockConfig={userCanLock ? { is_locked: false, action: lockPage } : undefined}
embedConfig={{
issueEmbedConfig: {
issues: issues,
fetchIssue: fetchIssue,
clickAction: issueWidgetClickAction,
},
}}
/>
)}
/>