mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: Removed Issue Embeds from the Document Editor (#3449)
* fix: issue embed going to next line when selected on slash commands * fix: issue suggestions selecting next embed on arrow down * fix: pages crashing, because of incorrect data type * chore: removed issue embeds from document editor and page interface * fix: upgraded issue widget card to show only Placeholder * fix: pricing url changes for issue embed placeholder * fix: build errors
This commit is contained in:
parent
8d3ea5bb3e
commit
1a1594e818
@ -1,56 +1,29 @@
|
||||
import Placeholder from "@tiptap/extension-placeholder";
|
||||
import { IssueWidgetExtension } from "src/ui/extensions/widgets/issue-embed-widget";
|
||||
|
||||
import { IIssueEmbedConfig } from "src/ui/extensions/widgets/issue-embed-widget/types";
|
||||
import { IssueWidgetPlaceholder } from "src/ui/extensions/widgets/issue-embed-widget";
|
||||
|
||||
import { SlashCommand, DragAndDrop } from "@plane/editor-extensions";
|
||||
import { ISlashCommandItem, UploadImage } from "@plane/editor-core";
|
||||
import { IssueSuggestions } from "src/ui/extensions/widgets/issue-embed-suggestion-list";
|
||||
import { LayersIcon } from "@plane/ui";
|
||||
import { UploadImage } from "@plane/editor-core";
|
||||
|
||||
export const DocumentEditorExtensions = (
|
||||
uploadFile: UploadImage,
|
||||
issueEmbedConfig?: IIssueEmbedConfig,
|
||||
setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void,
|
||||
setHideDragHandle?: (hideDragHandlerFromDragDrop: () => void) => void
|
||||
) => {
|
||||
const additionalOptions: ISlashCommandItem[] = [
|
||||
{
|
||||
key: "issue_embed",
|
||||
title: "Issue embed",
|
||||
description: "Embed an issue from the project.",
|
||||
searchTerms: ["issue", "link", "embed"],
|
||||
icon: <LayersIcon className="h-3.5 w-3.5" />,
|
||||
command: ({ editor, range }) => {
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.insertContentAt(
|
||||
range,
|
||||
"<p class='text-sm bg-gray-300 w-fit pl-3 pr-3 pt-1 pb-1 rounded shadow-sm'>#issue_</p>\n"
|
||||
)
|
||||
.run();
|
||||
},
|
||||
setHideDragHandle?: (hideDragHandlerFromDragDrop: () => void) => void,
|
||||
setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void
|
||||
) => [
|
||||
SlashCommand(uploadFile, setIsSubmitting),
|
||||
DragAndDrop(setHideDragHandle),
|
||||
Placeholder.configure({
|
||||
placeholder: ({ node }) => {
|
||||
if (node.type.name === "heading") {
|
||||
return `Heading ${node.attrs.level}`;
|
||||
}
|
||||
if (node.type.name === "image" || node.type.name === "table") {
|
||||
return "";
|
||||
}
|
||||
|
||||
return "Press '/' for commands...";
|
||||
},
|
||||
];
|
||||
includeChildren: true,
|
||||
}),
|
||||
IssueWidgetPlaceholder(),
|
||||
];
|
||||
|
||||
return [
|
||||
SlashCommand(uploadFile, setIsSubmitting, additionalOptions),
|
||||
DragAndDrop(setHideDragHandle),
|
||||
Placeholder.configure({
|
||||
placeholder: ({ node }) => {
|
||||
if (node.type.name === "heading") {
|
||||
return `Heading ${node.attrs.level}`;
|
||||
}
|
||||
if (node.type.name === "image" || node.type.name === "table") {
|
||||
return "";
|
||||
}
|
||||
|
||||
return "Press '/' for commands...";
|
||||
},
|
||||
includeChildren: true,
|
||||
}),
|
||||
IssueWidgetExtension({ issueEmbedConfig }),
|
||||
IssueSuggestions(issueEmbedConfig ? issueEmbedConfig.issues : []),
|
||||
];
|
||||
};
|
||||
|
@ -78,7 +78,6 @@ const IssueSuggestionList = ({
|
||||
const navigationKeys = ["ArrowUp", "ArrowDown", "Enter", "Tab"];
|
||||
const onKeyDown = (e: KeyboardEvent) => {
|
||||
if (navigationKeys.includes(e.key)) {
|
||||
e.preventDefault();
|
||||
// if (editor.isFocused) {
|
||||
// editor.chain().blur();
|
||||
// commandListContainer.current?.focus();
|
||||
@ -87,7 +86,6 @@ const IssueSuggestionList = ({
|
||||
setSelectedIndex(
|
||||
(selectedIndex + displayedItems[currentSection].length - 1) % displayedItems[currentSection].length
|
||||
);
|
||||
e.stopPropagation();
|
||||
return true;
|
||||
}
|
||||
if (e.key === "ArrowDown") {
|
||||
@ -102,12 +100,10 @@ const IssueSuggestionList = ({
|
||||
[currentSection]: [...prevItems[currentSection], ...nextItems],
|
||||
}));
|
||||
}
|
||||
e.stopPropagation();
|
||||
return true;
|
||||
}
|
||||
if (e.key === "Enter") {
|
||||
selectItem(currentSection, selectedIndex);
|
||||
e.stopPropagation();
|
||||
return true;
|
||||
}
|
||||
if (e.key === "Tab") {
|
||||
@ -115,7 +111,6 @@ const IssueSuggestionList = ({
|
||||
const nextSectionIndex = (currentSectionIndex + 1) % sections.length;
|
||||
setCurrentSection(sections[nextSectionIndex]);
|
||||
setSelectedIndex(0);
|
||||
e.stopPropagation();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -150,7 +145,7 @@ const IssueSuggestionList = ({
|
||||
<div
|
||||
id="issue-list-container"
|
||||
ref={commandListContainer}
|
||||
className="fixed z-[10] max-h-80 w-60 overflow-y-auto overflow-x-hidden rounded-md border border-custom-border-100 bg-custom-background-100 px-1 shadow-custom-shadow-xs transition-all"
|
||||
className=" fixed z-[10] max-h-80 w-60 overflow-y-auto overflow-x-hidden rounded-md border border-custom-border-100 bg-custom-background-100 px-1 shadow-custom-shadow-xs transition-all"
|
||||
>
|
||||
{sections.map((section) => {
|
||||
const sectionItems = displayedItems[section];
|
||||
@ -193,29 +188,35 @@ const IssueSuggestionList = ({
|
||||
</div>
|
||||
) : null;
|
||||
};
|
||||
|
||||
export const IssueListRenderer = () => {
|
||||
let component: ReactRenderer | null = null;
|
||||
let popup: any | null = null;
|
||||
|
||||
return {
|
||||
onStart: (props: { editor: Editor; clientRect?: (() => DOMRect | null) | null }) => {
|
||||
const container = document.querySelector(".frame-renderer") as HTMLElement;
|
||||
component = new ReactRenderer(IssueSuggestionList, {
|
||||
props,
|
||||
// @ts-ignore
|
||||
editor: props.editor,
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
popup = tippy("body", {
|
||||
popup = tippy(".frame-renderer", {
|
||||
flipbehavior: ["bottom", "top"],
|
||||
appendTo: () => document.querySelector(".frame-renderer") as HTMLElement,
|
||||
flip: true,
|
||||
flipOnUpdate: true,
|
||||
getReferenceClientRect: props.clientRect,
|
||||
appendTo: () => document.querySelector("#editor-container"),
|
||||
content: component.element,
|
||||
showOnCreate: true,
|
||||
interactive: true,
|
||||
trigger: "manual",
|
||||
placement: "bottom-start",
|
||||
});
|
||||
|
||||
container.addEventListener("scroll", () => {
|
||||
popup?.[0].destroy();
|
||||
});
|
||||
},
|
||||
onUpdate: (props: { editor: Editor; clientRect?: (() => DOMRect | null) | null }) => {
|
||||
component?.updateProps(props);
|
||||
@ -230,10 +231,20 @@ export const IssueListRenderer = () => {
|
||||
popup?.[0].hide();
|
||||
return true;
|
||||
}
|
||||
// @ts-ignore
|
||||
return component?.ref?.onKeyDown(props);
|
||||
|
||||
const navigationKeys = ["ArrowUp", "ArrowDown", "Enter", "Tab"];
|
||||
if (navigationKeys.includes(props.event.key)) {
|
||||
// @ts-ignore
|
||||
component?.ref?.onKeyDown(props);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
onExit: (e) => {
|
||||
const container = document.querySelector(".frame-renderer") as HTMLElement;
|
||||
if (container) {
|
||||
container.removeEventListener("scroll", () => {});
|
||||
}
|
||||
popup?.[0].destroy();
|
||||
setTimeout(() => {
|
||||
component?.destroy();
|
||||
|
@ -1,11 +1,3 @@
|
||||
import { IssueWidget } from "src/ui/extensions/widgets/issue-embed-widget/issue-widget-node";
|
||||
import { IIssueEmbedConfig } from "src/ui/extensions/widgets/issue-embed-widget/types";
|
||||
|
||||
interface IssueWidgetExtensionProps {
|
||||
issueEmbedConfig?: IIssueEmbedConfig;
|
||||
}
|
||||
|
||||
export const IssueWidgetExtension = ({ issueEmbedConfig }: IssueWidgetExtensionProps) =>
|
||||
IssueWidget.configure({
|
||||
issueEmbedConfig,
|
||||
});
|
||||
export const IssueWidgetPlaceholder = () => IssueWidget.configure({});
|
||||
|
@ -1,77 +1,33 @@
|
||||
// @ts-nocheck
|
||||
import { useState, useEffect } from "react";
|
||||
import { Button } from "@plane/ui";
|
||||
import { NodeViewWrapper } from "@tiptap/react";
|
||||
import { Avatar, AvatarGroup, Loader, PriorityIcon } from "@plane/ui";
|
||||
import { Calendar, AlertTriangle } from "lucide-react";
|
||||
import { Crown } from "lucide-react";
|
||||
|
||||
export const IssueWidgetCard = (props) => {
|
||||
const [loading, setLoading] = useState<number>(1);
|
||||
const [issueDetails, setIssueDetails] = useState();
|
||||
|
||||
useEffect(() => {
|
||||
props.issueEmbedConfig
|
||||
.fetchIssue(props.node.attrs.entity_identifier)
|
||||
.then((issue) => {
|
||||
setIssueDetails(issue);
|
||||
setLoading(0);
|
||||
})
|
||||
.catch(() => {
|
||||
setLoading(-1);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const completeIssueEmbedAction = () => {
|
||||
props.issueEmbedConfig.clickAction(issueDetails.id, props.node.attrs.title);
|
||||
};
|
||||
|
||||
return (
|
||||
<NodeViewWrapper className="issue-embed-component m-2">
|
||||
{loading == 0 ? (
|
||||
<div
|
||||
onClick={completeIssueEmbedAction}
|
||||
className={`${
|
||||
props.selected ? "border-custom-primary-200 border-[2px]" : ""
|
||||
} w-full cursor-pointer space-y-2 rounded-md border-[0.5px] border-custom-border-200 p-3 shadow-custom-shadow-2xs`}
|
||||
>
|
||||
<h5 className="text-xs text-custom-text-300">
|
||||
{issueDetails.project_detail.identifier}-{issueDetails.sequence_id}
|
||||
</h5>
|
||||
<h4 className="break-words text-sm font-medium">{issueDetails.name}</h4>
|
||||
<div className="flex flex-wrap items-center gap-x-3 gap-y-2">
|
||||
<div>
|
||||
<PriorityIcon priority={issueDetails.priority} />
|
||||
export const IssueWidgetCard = (props) => (
|
||||
<NodeViewWrapper className="issue-embed-component m-2">
|
||||
<div
|
||||
className={`${
|
||||
props.selected ? "border-custom-primary-200 border-[2px]" : ""
|
||||
} w-full h-[100px] cursor-pointer space-y-2 rounded-md border-[0.5px] border-custom-border-200 shadow-custom-shadow-2xs`}
|
||||
>
|
||||
<h5 className="h-[20%] text-xs text-custom-text-300 p-2">
|
||||
{props.node.attrs.project_identifier}-{props.node.attrs.sequence_id}
|
||||
</h5>
|
||||
<div className="relative h-[71%]">
|
||||
<div className="h-full backdrop-filter backdrop-blur-[30px] bg-custom-background-80 bg-opacity-30 flex items-center w-full justify-between gap-5 mt-2.5 pl-4 pr-5 py-3 max-md:max-w-full max-md:flex-wrap relative">
|
||||
<div className="flex gap-2 items-center">
|
||||
<div className="rounded">
|
||||
<Crown className="m-2" size={16} color="#FFBA18" />
|
||||
</div>
|
||||
<div>
|
||||
<AvatarGroup size="sm">
|
||||
{issueDetails.assignee_details.map((assignee) => (
|
||||
<Avatar key={assignee.id} name={assignee.display_name} src={assignee.avatar} className={"m-0"} />
|
||||
))}
|
||||
</AvatarGroup>
|
||||
<div className="text-custom-text text-sm">
|
||||
Embed and access issues in pages seamlessly, upgrade to plane pro now.
|
||||
</div>
|
||||
{issueDetails.target_date && (
|
||||
<div className="flex h-5 items-center gap-1 rounded border-[0.5px] border-custom-border-300 px-2.5 py-1 text-xs text-custom-text-100">
|
||||
<Calendar className="h-3 w-3" strokeWidth={1.5} />
|
||||
{new Date(issueDetails.target_date).toLocaleDateString()}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<a href="https://plane.so/pricing" target="_blank" rel="noreferrer">
|
||||
<Button>Upgrade</Button>
|
||||
</a>
|
||||
</div>
|
||||
) : loading == -1 ? (
|
||||
<div className="flex items-center gap-[8px] rounded border-2 border-[#D97706] bg-[#FFFBEB] pb-[10px] pl-[13px] pt-[10px] text-[#D97706]">
|
||||
<AlertTriangle color={"#D97706"} />
|
||||
{"This Issue embed is not found in any project. It can no longer be updated or accessed from here."}
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-full space-y-2 rounded-md border-[0.5px] border-custom-border-200 p-3 shadow-custom-shadow-2xs">
|
||||
<Loader className={"px-6"}>
|
||||
<Loader.Item height={"30px"} />
|
||||
<div className={"mt-3 space-y-2"}>
|
||||
<Loader.Item height={"20px"} width={"70%"} />
|
||||
<Loader.Item height={"20px"} width={"60%"} />
|
||||
</div>
|
||||
</Loader>
|
||||
</div>
|
||||
)}
|
||||
</NodeViewWrapper>
|
||||
);
|
||||
};
|
||||
</div>
|
||||
</div>
|
||||
</NodeViewWrapper>
|
||||
);
|
||||
|
@ -34,9 +34,7 @@ export const IssueWidget = Node.create({
|
||||
},
|
||||
|
||||
addNodeView() {
|
||||
return ReactNodeViewRenderer((props: Object) => (
|
||||
<IssueWidgetCard {...props} issueEmbedConfig={this.options.issueEmbedConfig} />
|
||||
));
|
||||
return ReactNodeViewRenderer((props: Object) => <IssueWidgetCard {...props} />);
|
||||
},
|
||||
|
||||
parseHTML() {
|
||||
|
@ -1,9 +0,0 @@
|
||||
export interface IEmbedConfig {
|
||||
issueEmbedConfig: IIssueEmbedConfig;
|
||||
}
|
||||
|
||||
export interface IIssueEmbedConfig {
|
||||
fetchIssue: (issueId: string) => Promise<any>;
|
||||
clickAction: (issueId: string, issueTitle: string) => void;
|
||||
issues: Array<any>;
|
||||
}
|
@ -10,7 +10,6 @@ import { DocumentDetails } from "src/types/editor-types";
|
||||
import { PageRenderer } from "src/ui/components/page-renderer";
|
||||
import { getMenuOptions } from "src/utils/menu-options";
|
||||
import { useRouter } from "next/router";
|
||||
import { IEmbedConfig } from "src/ui/extensions/widgets/issue-embed-widget/types";
|
||||
|
||||
interface IDocumentEditor {
|
||||
// document info
|
||||
@ -47,7 +46,6 @@ interface IDocumentEditor {
|
||||
duplicationConfig?: IDuplicationConfig;
|
||||
pageLockConfig?: IPageLockConfig;
|
||||
pageArchiveConfig?: IPageArchiveConfig;
|
||||
embedConfig?: IEmbedConfig;
|
||||
}
|
||||
interface DocumentEditorProps extends IDocumentEditor {
|
||||
forwardedRef?: React.Ref<EditorHandle>;
|
||||
@ -75,13 +73,11 @@ const DocumentEditor = ({
|
||||
duplicationConfig,
|
||||
pageLockConfig,
|
||||
pageArchiveConfig,
|
||||
embedConfig,
|
||||
updatePageTitle,
|
||||
cancelUploadImage,
|
||||
onActionCompleteHandler,
|
||||
rerenderOnPropsChange,
|
||||
}: IDocumentEditor) => {
|
||||
// const [alert, setAlert] = useState<string>("")
|
||||
const { markings, updateMarkings } = useEditorMarkings();
|
||||
const [sidePeekVisible, setSidePeekVisible] = useState(true);
|
||||
const router = useRouter();
|
||||
@ -112,12 +108,7 @@ const DocumentEditor = ({
|
||||
cancelUploadImage,
|
||||
rerenderOnPropsChange,
|
||||
forwardedRef,
|
||||
extensions: DocumentEditorExtensions(
|
||||
uploadFile,
|
||||
embedConfig?.issueEmbedConfig,
|
||||
setIsSubmitting,
|
||||
setHideDragHandleFunction
|
||||
),
|
||||
extensions: DocumentEditorExtensions(uploadFile, setHideDragHandleFunction, setIsSubmitting),
|
||||
});
|
||||
|
||||
if (!editor) {
|
||||
@ -158,11 +149,11 @@ const DocumentEditor = ({
|
||||
documentDetails={documentDetails}
|
||||
isSubmitting={isSubmitting}
|
||||
/>
|
||||
<div className="flex h-full w-full overflow-y-auto">
|
||||
<div className="flex h-full w-full overflow-y-auto frame-renderer">
|
||||
<div className="sticky top-0 h-full w-56 flex-shrink-0 lg:w-72">
|
||||
<SummarySideBar editor={editor} markings={markings} sidePeekVisible={sidePeekVisible} />
|
||||
</div>
|
||||
<div className="h-full w-[calc(100%-14rem)] lg:w-[calc(100%-18rem-18rem)]">
|
||||
<div className="h-full w-[calc(100%-14rem)] lg:w-[calc(100%-18rem-18rem)] page-renderer">
|
||||
<PageRenderer
|
||||
onActionCompleteHandler={onActionCompleteHandler}
|
||||
hideDragHandle={hideDragHandleOnMouseLeave}
|
||||
|
@ -4,12 +4,11 @@ import { useState, forwardRef, useEffect } from "react";
|
||||
import { EditorHeader } from "src/ui/components/editor-header";
|
||||
import { PageRenderer } from "src/ui/components/page-renderer";
|
||||
import { SummarySideBar } from "src/ui/components/summary-side-bar";
|
||||
import { IssueWidgetExtension } from "src/ui/extensions/widgets/issue-embed-widget";
|
||||
import { IEmbedConfig } from "src/ui/extensions/widgets/issue-embed-widget/types";
|
||||
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";
|
||||
|
||||
interface IDocumentReadOnlyEditor {
|
||||
value: string;
|
||||
@ -29,7 +28,6 @@ interface IDocumentReadOnlyEditor {
|
||||
message: string;
|
||||
type: "success" | "error" | "warning" | "info";
|
||||
}) => void;
|
||||
embedConfig?: IEmbedConfig;
|
||||
}
|
||||
|
||||
interface DocumentReadOnlyEditorProps extends IDocumentReadOnlyEditor {
|
||||
@ -51,7 +49,6 @@ const DocumentReadOnlyEditor = ({
|
||||
pageDuplicationConfig,
|
||||
pageLockConfig,
|
||||
pageArchiveConfig,
|
||||
embedConfig,
|
||||
rerenderOnPropsChange,
|
||||
onActionCompleteHandler,
|
||||
}: DocumentReadOnlyEditorProps) => {
|
||||
@ -63,7 +60,7 @@ const DocumentReadOnlyEditor = ({
|
||||
value,
|
||||
forwardedRef,
|
||||
rerenderOnPropsChange,
|
||||
extensions: [IssueWidgetExtension({ issueEmbedConfig: embedConfig?.issueEmbedConfig })],
|
||||
extensions: [IssueWidgetPlaceholder()],
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@ -105,11 +102,11 @@ const DocumentReadOnlyEditor = ({
|
||||
documentDetails={documentDetails}
|
||||
archivedAt={pageArchiveConfig && pageArchiveConfig.archived_at}
|
||||
/>
|
||||
<div className="flex h-full w-full overflow-y-auto">
|
||||
<div className="flex h-full w-full overflow-y-auto frame-renderer">
|
||||
<div className="sticky top-0 h-full w-56 flex-shrink-0 lg:w-80">
|
||||
<SummarySideBar editor={editor} markings={markings} sidePeekVisible={sidePeekVisible} />
|
||||
</div>
|
||||
<div className="h-full w-[calc(100%-14rem)] lg:w-[calc(100%-18rem-18rem)]">
|
||||
<div className="h-full w-[calc(100%-14rem)] lg:w-[calc(100%-18rem-18rem)] page-renderer">
|
||||
<PageRenderer
|
||||
onActionCompleteHandler={onActionCompleteHandler}
|
||||
updatePageTitle={() => Promise.resolve()}
|
||||
|
@ -1,48 +0,0 @@
|
||||
import { TIssue } from "@plane/types";
|
||||
import { PROJECT_ISSUES_LIST, STATES_LIST } from "constants/fetch-keys";
|
||||
import { EIssuesStoreType } from "constants/issue";
|
||||
import { StoreContext } from "contexts/store-context";
|
||||
import { autorun, toJS } from "mobx";
|
||||
import { useContext } from "react";
|
||||
import { IssueService } from "services/issue";
|
||||
import useSWR from "swr";
|
||||
import { useIssueDetail, useIssues, 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 } = 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 = async (issueId: string) => issuesWithStateAndProject.find((issue) => issue.id === issueId);
|
||||
|
||||
const issueWidgetClickAction = (issueId: string) => {
|
||||
if (!workspaceSlug || !projectId) return;
|
||||
|
||||
setPeekIssue({ workspaceSlug, projectId: projectId, issueId });
|
||||
};
|
||||
|
||||
return {
|
||||
issues: issuesWithStateAndProject,
|
||||
fetchIssue,
|
||||
issueWidgetClickAction,
|
||||
};
|
||||
};
|
@ -5,7 +5,8 @@ import { useRouter } from "next/router";
|
||||
import { ReactElement, useEffect, useRef, useState } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
// hooks
|
||||
import { useApplication, useIssues, usePage, useUser, useWorkspace } from "hooks/store";
|
||||
|
||||
import { useApplication, usePage, useUser, useWorkspace } from "hooks/store";
|
||||
import useReloadConfirmations from "hooks/use-reload-confirmation";
|
||||
import useToast from "hooks/use-toast";
|
||||
// services
|
||||
@ -27,15 +28,10 @@ import { NextPageWithLayout } from "lib/types";
|
||||
// constants
|
||||
import { EUserProjectRoles } from "constants/project";
|
||||
import { useProjectPages } from "hooks/store/use-project-specific-pages";
|
||||
import { useIssueEmbeds } from "hooks/use-issue-embeds";
|
||||
import { IssuePeekOverview } from "components/issues";
|
||||
import { PROJECT_ISSUES_LIST } from "constants/fetch-keys";
|
||||
import { IssueService } from "services/issue";
|
||||
import { EIssuesStoreType } from "constants/issue";
|
||||
|
||||
// services
|
||||
const fileService = new FileService();
|
||||
const issueService = new IssueService();
|
||||
|
||||
const PageDetailsPage: NextPageWithLayout = observer(() => {
|
||||
// states
|
||||
@ -91,8 +87,6 @@ const PageDetailsPage: NextPageWithLayout = observer(() => {
|
||||
: null
|
||||
);
|
||||
|
||||
const { issues, fetchIssue, issueWidgetClickAction } = useIssueEmbeds();
|
||||
|
||||
const pageStore = usePage(pageId as string);
|
||||
|
||||
useEffect(
|
||||
@ -262,7 +256,7 @@ const PageDetailsPage: NextPageWithLayout = observer(() => {
|
||||
const userCanLock =
|
||||
currentProjectRole && [EUserProjectRoles.ADMIN, EUserProjectRoles.MEMBER].includes(currentProjectRole);
|
||||
|
||||
return pageIdMobx && issues ? (
|
||||
return pageIdMobx ? (
|
||||
<div className="flex h-full flex-col justify-between">
|
||||
<div className="h-full w-full overflow-hidden">
|
||||
{isPageReadOnly ? (
|
||||
@ -291,13 +285,6 @@ const PageDetailsPage: NextPageWithLayout = observer(() => {
|
||||
}
|
||||
: undefined
|
||||
}
|
||||
embedConfig={{
|
||||
issueEmbedConfig: {
|
||||
issues: issues,
|
||||
fetchIssue: fetchIssue,
|
||||
clickAction: issueWidgetClickAction,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<div className="relative h-full w-full overflow-hidden">
|
||||
@ -341,13 +328,6 @@ const PageDetailsPage: NextPageWithLayout = observer(() => {
|
||||
: undefined
|
||||
}
|
||||
pageLockConfig={userCanLock ? { is_locked: false, action: lockPage } : undefined}
|
||||
embedConfig={{
|
||||
issueEmbedConfig: {
|
||||
issues: issues,
|
||||
fetchIssue: fetchIssue,
|
||||
clickAction: issueWidgetClickAction,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
Loading…
Reference in New Issue
Block a user