Compare commits

..
55 changed files with 341 additions and 139 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "admin",
"version": "0.24.0",
"version": "0.23.1",
"private": true,
"scripts": {
"dev": "turbo run develop",
+1 -1
View File
@@ -1,4 +1,4 @@
{
"name": "plane-api",
"version": "0.24.0"
"version": "0.23.1"
}
+3 -1
View File
@@ -258,7 +258,9 @@ class ProjectAPIEndpoint(BaseAPIView):
ProjectSerializer(project).data, cls=DjangoJSONEncoder
)
intake_view = request.data.get("inbox_view", project.intake_view)
intake_view = request.data.get(
"inbox_view", request.data.get("intake_view", False)
)
if project.archived_at:
return Response(
+3 -1
View File
@@ -384,9 +384,11 @@ class ProjectViewSet(BaseViewSet):
)
workspace = Workspace.objects.get(slug=slug)
intake_view = request.data.get(
"inbox_view", request.data.get("intake_view", False)
)
project = Project.objects.get(pk=pk)
intake_view = request.data.get("inbox_view", project.intake_view)
current_instance = json.dumps(
ProjectSerializer(project).data, cls=DjangoJSONEncoder
)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "live",
"version": "0.24.0",
"version": "0.23.1",
"description": "",
"main": "./src/server.ts",
"private": true,
+2 -2
View File
@@ -1,6 +1,6 @@
{
"repository": "https://github.com/makeplane/plane.git",
"version": "0.24.0",
"version": "0.23.1",
"license": "AGPL-3.0",
"private": true,
"workspaces": [
@@ -22,7 +22,7 @@
"devDependencies": {
"prettier": "latest",
"prettier-plugin-tailwindcss": "^0.5.4",
"turbo": "^2.3.3"
"turbo": "^2.3.2"
},
"packageManager": "yarn@1.22.22",
"name": "plane"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@plane/constants",
"version": "0.24.0",
"version": "0.23.1",
"private": true,
"main": "./index.ts"
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@plane/editor",
"version": "0.24.0",
"version": "0.23.1",
"description": "Core Editor that powers Plane",
"private": true,
"main": "./dist/index.mjs",
@@ -1,7 +1,7 @@
import React, { useRef, useState, useCallback, useLayoutEffect, useEffect } from "react";
import { NodeSelection } from "@tiptap/pm/state";
// extensions
import { CustomBaseImageNodeViewProps, ImageToolbarRoot } from "@/extensions/custom-image";
import { CustoBaseImageNodeViewProps, ImageToolbarRoot } from "@/extensions/custom-image";
// helpers
import { cn } from "@/helpers/common";
@@ -37,7 +37,7 @@ const ensurePixelString = <TDefault,>(value: Pixel | TDefault | number | undefin
return value;
};
type CustomImageBlockProps = CustomBaseImageNodeViewProps & {
type CustomImageBlockProps = CustoBaseImageNodeViewProps & {
imageFromFileSystem: string;
setFailedToLoadImage: (isError: boolean) => void;
editorContainer: HTMLDivElement | null;
@@ -3,7 +3,7 @@ import { Editor, NodeViewProps, NodeViewWrapper } from "@tiptap/react";
// extensions
import { CustomImageBlock, CustomImageUploader, ImageAttributes } from "@/extensions/custom-image";
export type CustomBaseImageNodeViewProps = {
export type CustoBaseImageNodeViewProps = {
getPos: () => number;
editor: Editor;
node: NodeViewProps["node"] & {
@@ -13,7 +13,7 @@ export type CustomBaseImageNodeViewProps = {
selected: boolean;
};
export type CustomImageNodeProps = NodeViewProps & CustomBaseImageNodeViewProps;
export type CustomImageNodeProps = NodeViewProps & CustoBaseImageNodeViewProps;
export const CustomImageNode = (props: CustomImageNodeProps) => {
const { getPos, editor, node, updateAttributes, selected } = props;
@@ -5,9 +5,9 @@ import { cn } from "@/helpers/common";
// hooks
import { useUploader, useDropZone, uploadFirstImageAndInsertRemaining } from "@/hooks/use-file-upload";
// extensions
import { CustomBaseImageNodeViewProps, getImageComponentImageFileMap } from "@/extensions/custom-image";
import { CustoBaseImageNodeViewProps, getImageComponentImageFileMap } from "@/extensions/custom-image";
type CustomImageUploaderProps = CustomBaseImageNodeViewProps & {
type CustomImageUploaderProps = CustoBaseImageNodeViewProps & {
maxFileSize: number;
loadImageFromFileSystem: (file: string) => void;
failedToLoadImage: boolean;
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@plane/eslint-config",
"private": true,
"version": "0.24.0",
"version": "0.23.1",
"files": [
"library.js",
"next.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@plane/helpers",
"version": "0.24.0",
"version": "0.23.1",
"description": "Helper functions shared across multiple apps internally",
"private": true,
"main": "./dist/index.js",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "tailwind-config-custom",
"version": "0.24.0",
"version": "0.23.1",
"description": "common tailwind configuration across monorepo",
"main": "index.js",
"private": true,
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@plane/types",
"version": "0.24.0",
"version": "0.23.1",
"private": true,
"types": "./src/index.d.ts",
"main": "./src/index.d.ts"
-1
View File
@@ -95,7 +95,6 @@ export type TIssuesResponse = {
total_pages: number;
extra_stats: null;
results: TIssueResponseResults;
total_results: number;
};
export type TBulkIssueProperties = Pick<
+1 -2
View File
@@ -49,7 +49,7 @@ export type TPageFilters = {
export type TPageEmbedType = "mention" | "issue";
export type TPageVersion = {
export type TEditorVersion = {
created_at: string;
created_by: string;
deleted_at: string | null;
@@ -59,7 +59,6 @@ export type TPageVersion = {
id: string;
last_saved_at: string;
owned_by: string;
page: string;
updated_at: string;
updated_by: string;
workspace: string;
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@plane/typescript-config",
"version": "0.24.0",
"version": "0.23.1",
"private": true,
"files": [
"base.json",
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "@plane/ui",
"description": "UI components shared across multiple apps internally",
"private": true,
"version": "0.24.0",
"version": "0.23.1",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "space",
"version": "0.24.0",
"version": "0.23.1",
"private": true,
"scripts": {
"dev": "turbo run develop",
@@ -46,6 +46,7 @@ export const ProjectArchivesHeader: FC<TProps> = observer((props: TProps) => {
type="text"
link={
<BreadcrumbLink
href={`/${workspaceSlug}/projects`}
label={currentProjectDetails?.name ?? "Project"}
icon={
currentProjectDetails && (
@@ -38,6 +38,7 @@ export const ProjectArchivedIssueDetailsHeader = observer(() => {
type="text"
link={
<BreadcrumbLink
href={`/${workspaceSlug}/projects`}
label={currentProjectDetails?.name ?? "Project"}
icon={
currentProjectDetails && (
@@ -172,6 +172,7 @@ export const CycleIssuesHeader: React.FC = observer(() => {
<span className="hidden md:block">
<BreadcrumbLink
label={currentProjectDetails?.name ?? "Project"}
href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
icon={
currentProjectDetails && (
<span className="grid h-4 w-4 flex-shrink-0 place-items-center">
@@ -38,6 +38,7 @@ export const CyclesListHeader: FC = observer(() => {
link={
<BreadcrumbLink
label={currentProjectDetails?.name ?? "Project"}
href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
icon={
currentProjectDetails && (
<span className="grid place-items-center flex-shrink-0 h-4 w-4">
@@ -99,6 +99,7 @@ export const ProjectDraftIssueHeader: FC = observer(() => {
type="text"
link={
<BreadcrumbLink
href={`/${workspaceSlug}/projects`}
label={currentProjectDetails?.name ?? "Project"}
icon={
currentProjectDetails && (
@@ -32,6 +32,7 @@ export const ProjectIssueDetailsHeader = observer(() => {
type="text"
link={
<BreadcrumbLink
href={`/${workspaceSlug}/projects`}
label={currentProjectDetails?.name ?? "Project"}
icon={
currentProjectDetails && (
@@ -54,6 +54,7 @@ export const ProjectIssuesHeader = observer(() => {
type="text"
link={
<BreadcrumbLink
href={`/${workspaceSlug}/projects`}
label={currentProjectDetails?.name ?? "Project"}
icon={
currentProjectDetails ? (
@@ -171,6 +171,7 @@ export const ModuleIssuesHeader: React.FC = observer(() => {
<span className="hidden md:block">
<BreadcrumbLink
label={currentProjectDetails?.name ?? "Project"}
href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
icon={
currentProjectDetails && (
<span className="grid h-4 w-4 flex-shrink-0 place-items-center">
@@ -39,6 +39,7 @@ export const ModulesListHeader: React.FC = observer(() => {
type="text"
link={
<BreadcrumbLink
href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
label={currentProjectDetails?.name ?? "Project"}
icon={
currentProjectDetails && (
@@ -77,6 +77,7 @@ export const PageDetailsHeader = observer(() => {
<span>
<span className="hidden md:block">
<BreadcrumbLink
href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
label={currentProjectDetails?.name ?? "Project"}
icon={
currentProjectDetails && (
@@ -69,6 +69,7 @@ export const PagesListHeader = observer(() => {
type="text"
link={
<BreadcrumbLink
href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
label={currentProjectDetails?.name ?? "Project"}
icon={
currentProjectDetails && (
@@ -34,6 +34,7 @@ export const ProjectSettingHeader: FC = observer(() => {
type="text"
link={
<BreadcrumbLink
href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
label={currentProjectDetails?.name ?? "Project"}
icon={
currentProjectDetails && (
@@ -144,6 +144,7 @@ export const ProjectViewIssuesHeader: React.FC = observer(() => {
type="text"
link={
<BreadcrumbLink
href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
label={currentProjectDetails?.name ?? "Project"}
icon={
currentProjectDetails && (
@@ -27,6 +27,7 @@ export const ProjectViewsHeader = observer(() => {
type="text"
link={
<BreadcrumbLink
href={`/${workspaceSlug}/projects/${currentProjectDetails?.id}/issues`}
label={currentProjectDetails?.name ?? "Project"}
icon={
currentProjectDetails && (
@@ -39,6 +39,7 @@ export const ProjectInboxHeader: FC = observer(() => {
type="text"
link={
<BreadcrumbLink
href={`/${workspaceSlug}/projects`}
label={currentProjectDetails?.name ?? "Project"}
icon={
currentProjectDetails && (
+1
View File
@@ -1,3 +1,4 @@
export * from "./lite-text-editor";
export * from "./pdf";
export * from "./rich-text-editor";
export * from "./version-history";
@@ -0,0 +1,11 @@
import { TEditorVersion } from "@plane/types";
export type TVersionEditorProps = {
activeVersion: string | null;
currentVersionDescription: string | null;
isCurrentVersionActive: boolean;
versionDetails: TEditorVersion | undefined;
};
export * from "./issue-version-editor";
export * from "./page-version-editor";
@@ -0,0 +1,70 @@
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane ui
import { Loader } from "@plane/ui";
// components
import { RichTextReadOnlyEditor } from "@/components/editor";
// local types
import { TVersionEditorProps } from ".";
export const IssueVersionEditor: React.FC<TVersionEditorProps> = observer((props) => {
const { activeVersion, currentVersionDescription, isCurrentVersionActive, versionDetails } = props;
// params
const { workspaceSlug, projectId } = useParams();
if (!isCurrentVersionActive && !versionDetails)
return (
<div className="size-full px-5">
<Loader className="relative space-y-4">
<Loader.Item width="50%" height="36px" />
<div className="space-y-2">
<div className="py-2">
<Loader.Item width="100%" height="36px" />
</div>
<Loader.Item width="80%" height="22px" />
<div className="relative flex items-center gap-2">
<Loader.Item width="30px" height="30px" />
<Loader.Item width="30%" height="22px" />
</div>
<div className="py-2">
<Loader.Item width="60%" height="36px" />
</div>
<Loader.Item width="70%" height="22px" />
<Loader.Item width="30%" height="22px" />
<div className="relative flex items-center gap-2">
<Loader.Item width="30px" height="30px" />
<Loader.Item width="30%" height="22px" />
</div>
<div className="py-2">
<Loader.Item width="50%" height="30px" />
</div>
<Loader.Item width="100%" height="22px" />
<div className="py-2">
<Loader.Item width="30%" height="30px" />
</div>
<Loader.Item width="30%" height="22px" />
<div className="relative flex items-center gap-2">
<div className="py-2">
<Loader.Item width="30px" height="30px" />
</div>
<Loader.Item width="30%" height="22px" />
</div>
</div>
</Loader>
</div>
);
const description = isCurrentVersionActive ? currentVersionDescription : versionDetails?.description_html;
if (description === undefined || description?.trim() === "") return null;
return (
<RichTextReadOnlyEditor
id={activeVersion ?? ""}
initialValue={description ?? "<p></p>"}
containerClassName="p-0 pb-64 border-none"
editorClassName="pl-10"
workspaceSlug={workspaceSlug?.toString() ?? ""}
projectId={projectId?.toString() ?? ""}
/>
);
});
@@ -1,27 +1,21 @@
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane editor
import { DocumentReadOnlyEditorWithRef, TDisplayConfig } from "@plane/editor";
import { DocumentReadOnlyEditorWithRef } from "@plane/editor";
// plane types
import { IUserLite, TPageVersion } from "@plane/types";
import { IUserLite } from "@plane/types";
// plane ui
import { Loader } from "@plane/ui";
// helpers
import { getReadOnlyEditorFileHandlers } from "@/helpers/editor.helper";
// hooks
import { useMember, useMention, useUser } from "@/hooks/store";
import { usePageFilters } from "@/hooks/use-page-filters";
// plane web hooks
import { useIssueEmbed } from "@/plane-web/hooks/use-issue-embed";
// local types
import { TVersionEditorProps } from ".";
export type TVersionEditorProps = {
activeVersion: string | null;
currentVersionDescription: string | null;
isCurrentVersionActive: boolean;
versionDetails: TPageVersion | undefined;
};
export const PagesVersionEditor: React.FC<TVersionEditorProps> = observer((props) => {
export const PageVersionEditor: React.FC<TVersionEditorProps> = observer((props) => {
const { activeVersion, currentVersionDescription, isCurrentVersionActive, versionDetails } = props;
// params
const { workspaceSlug, projectId } = useParams();
@@ -43,13 +37,6 @@ export const PagesVersionEditor: React.FC<TVersionEditorProps> = observer((props
members: projectMemberDetails,
user: currentUser ?? undefined,
});
// page filters
const { fontSize, fontStyle } = usePageFilters();
const displayConfig: TDisplayConfig = {
fontSize,
fontStyle,
};
if (!isCurrentVersionActive && !versionDetails)
return (
@@ -101,7 +88,6 @@ export const PagesVersionEditor: React.FC<TVersionEditorProps> = observer((props
id={activeVersion ?? ""}
initialValue={description ?? "<p></p>"}
containerClassName="p-0 pb-64 border-none"
displayConfig={displayConfig}
editorClassName="pl-10"
fileHandler={getReadOnlyEditorFileHandlers({
projectId: projectId?.toString() ?? "",
@@ -1,4 +1,4 @@
export * from "./editor";
export * from "./editors";
export * from "./main-content";
export * from "./root";
export * from "./sidebar-list-item";
@@ -3,34 +3,34 @@ import { observer } from "mobx-react";
import useSWR from "swr";
import { TriangleAlert } from "lucide-react";
// plane types
import { TPageVersion } from "@plane/types";
import { TEditorVersion } from "@plane/types";
// plane ui
import { Button, setToast, TOAST_TYPE } from "@plane/ui";
// components
import { TVersionEditorProps } from "@/components/pages";
// helpers
import { renderFormattedDate, renderFormattedTime } from "@/helpers/date-time.helper";
// local types
import { TVersionEditorProps } from ".";
type Props = {
activeVersion: string | null;
currentVersionDescription: string | null;
editorComponent: React.FC<TVersionEditorProps>;
fetchVersionDetails: (pageId: string, versionId: string) => Promise<TPageVersion | undefined>;
entityId: string;
fetchVersionDetails: (entityId: string, versionId: string) => Promise<TEditorVersion | undefined>;
handleClose: () => void;
handleRestore: (descriptionHTML: string) => Promise<void>;
pageId: string;
restoreEnabled: boolean;
};
export const PageVersionsMainContent: React.FC<Props> = observer((props) => {
export const EditorVersionHistoryMainContent: React.FC<Props> = observer((props) => {
const {
activeVersion,
currentVersionDescription,
editorComponent,
entityId,
fetchVersionDetails,
handleClose,
handleRestore,
pageId,
restoreEnabled,
} = props;
// states
@@ -42,8 +42,8 @@ export const PageVersionsMainContent: React.FC<Props> = observer((props) => {
error: versionDetailsError,
mutate: mutateVersionDetails,
} = useSWR(
pageId && activeVersion && activeVersion !== "current" ? `PAGE_VERSION_${activeVersion}` : null,
pageId && activeVersion && activeVersion !== "current" ? () => fetchVersionDetails(pageId, activeVersion) : null
entityId && activeVersion && activeVersion !== "current" ? `EDITOR_VERSION_${activeVersion}` : null,
entityId && activeVersion && activeVersion !== "current" ? () => fetchVersionDetails(entityId, activeVersion) : null
);
const isCurrentVersionActive = activeVersion === "current";
@@ -55,14 +55,14 @@ export const PageVersionsMainContent: React.FC<Props> = observer((props) => {
.then(() => {
setToast({
type: TOAST_TYPE.SUCCESS,
title: "Page version restored.",
title: "Version restored.",
});
handleClose();
})
.catch(() =>
setToast({
type: TOAST_TYPE.ERROR,
title: "Failed to restore page version.",
title: "Failed to restore version.",
})
)
.finally(() => setIsRestoring(false));
@@ -1,35 +1,35 @@
import { observer } from "mobx-react";
// plane types
import { TPageVersion } from "@plane/types";
// components
import { PageVersionsMainContent, PageVersionsSidebarRoot, TVersionEditorProps } from "@/components/pages";
import { TEditorVersion } from "@plane/types";
// helpers
import { cn } from "@/helpers/common.helper";
// local components
import { EditorVersionHistoryMainContent, EditorVersionHistorySidebarRoot, TVersionEditorProps } from ".";
type Props = {
activeVersion: string | null;
currentVersionDescription: string | null;
editorComponent: React.FC<TVersionEditorProps>;
fetchAllVersions: (pageId: string) => Promise<TPageVersion[] | undefined>;
fetchVersionDetails: (pageId: string, versionId: string) => Promise<TPageVersion | undefined>;
entityId: string;
fetchAllVersions: (entityId: string) => Promise<TEditorVersion[] | undefined>;
fetchVersionDetails: (entityId: string, versionId: string) => Promise<TEditorVersion | undefined>;
handleRestore: (descriptionHTML: string) => Promise<void>;
isOpen: boolean;
onClose: () => void;
pageId: string;
restoreEnabled: boolean;
};
export const PageVersionsOverlay: React.FC<Props> = observer((props) => {
export const EditorVersionHistoryOverlay: React.FC<Props> = observer((props) => {
const {
activeVersion,
currentVersionDescription,
editorComponent,
entityId,
fetchAllVersions,
fetchVersionDetails,
handleRestore,
isOpen,
onClose,
pageId,
restoreEnabled,
} = props;
@@ -46,22 +46,22 @@ export const PageVersionsOverlay: React.FC<Props> = observer((props) => {
}
)}
>
<PageVersionsMainContent
<EditorVersionHistoryMainContent
activeVersion={activeVersion}
currentVersionDescription={currentVersionDescription}
editorComponent={editorComponent}
entityId={entityId}
fetchVersionDetails={fetchVersionDetails}
handleClose={handleClose}
handleRestore={handleRestore}
pageId={pageId}
restoreEnabled={restoreEnabled}
/>
<PageVersionsSidebarRoot
<EditorVersionHistorySidebarRoot
activeVersion={activeVersion}
entityId={entityId}
fetchAllVersions={fetchAllVersions}
handleClose={handleClose}
isOpen={isOpen}
pageId={pageId}
/>
</div>
);
@@ -1,7 +1,7 @@
import { observer } from "mobx-react";
import Link from "next/link";
// plane types
import { TPageVersion } from "@plane/types";
import { TEditorVersion } from "@plane/types";
// plane ui
import { Avatar } from "@plane/ui";
// helpers
@@ -14,10 +14,10 @@ import { useMember } from "@/hooks/store";
type Props = {
href: string;
isActive: boolean;
version: TPageVersion;
version: TEditorVersion;
};
export const PlaneVersionsSidebarListItem: React.FC<Props> = observer((props) => {
export const EditorVersionHistorySidebarListItem: React.FC<Props> = observer((props) => {
const { href, isActive, version } = props;
// store hooks
const { getUserDetails } = useMember();
@@ -3,25 +3,25 @@ import Link from "next/link";
import useSWR from "swr";
import { TriangleAlert } from "lucide-react";
// plane types
import { TPageVersion } from "@plane/types";
import { TEditorVersion } from "@plane/types";
// plane ui
import { Button, Loader } from "@plane/ui";
// components
import { PlaneVersionsSidebarListItem } from "@/components/pages";
// helpers
import { cn } from "@/helpers/common.helper";
// hooks
import { useQueryParams } from "@/hooks/use-query-params";
// local components
import { EditorVersionHistorySidebarListItem } from ".";
type Props = {
activeVersion: string | null;
fetchAllVersions: (pageId: string) => Promise<TPageVersion[] | undefined>;
entityId: string;
fetchAllVersions: (entityId: string) => Promise<TEditorVersion[] | undefined>;
isOpen: boolean;
pageId: string;
};
export const PageVersionsSidebarList: React.FC<Props> = (props) => {
const { activeVersion, fetchAllVersions, isOpen, pageId } = props;
export const EditorVersionHistorySidebarList: React.FC<Props> = (props) => {
const { activeVersion, entityId, fetchAllVersions, isOpen } = props;
// states
const [isRetrying, setIsRetrying] = useState(false);
// update query params
@@ -32,8 +32,8 @@ export const PageVersionsSidebarList: React.FC<Props> = (props) => {
error: versionsListError,
mutate: mutateVersionsList,
} = useSWR(
pageId && isOpen ? `PAGE_VERSIONS_LIST_${pageId}` : null,
pageId && isOpen ? () => fetchAllVersions(pageId) : null
entityId && isOpen ? `EDITOR_VERSIONS_LIST_${entityId}` : null,
entityId && isOpen ? () => fetchAllVersions(entityId) : null
);
const handleRetry = async () => {
@@ -78,7 +78,7 @@ export const PageVersionsSidebarList: React.FC<Props> = (props) => {
</div>
) : versionsList ? (
versionsList.map((version) => (
<PlaneVersionsSidebarListItem
<EditorVersionHistorySidebarListItem
key={version.id}
href={getVersionLink(version.id)}
isActive={activeVersion === version.id}
@@ -1,19 +1,19 @@
import { X } from "lucide-react";
// plane types
import { TPageVersion } from "@plane/types";
// components
import { PageVersionsSidebarList } from "@/components/pages";
import { TEditorVersion } from "@plane/types";
// local components
import { EditorVersionHistorySidebarList } from ".";
type Props = {
activeVersion: string | null;
fetchAllVersions: (pageId: string) => Promise<TPageVersion[] | undefined>;
entityId: string;
fetchAllVersions: (entityId: string) => Promise<TEditorVersion[] | undefined>;
handleClose: () => void;
isOpen: boolean;
pageId: string;
};
export const PageVersionsSidebarRoot: React.FC<Props> = (props) => {
const { activeVersion, fetchAllVersions, handleClose, isOpen, pageId } = props;
export const EditorVersionHistorySidebarRoot: React.FC<Props> = (props) => {
const { activeVersion, entityId, fetchAllVersions, handleClose, isOpen } = props;
return (
<div className="flex-shrink-0 py-4 border-l border-custom-border-200 flex flex-col">
@@ -27,11 +27,11 @@ export const PageVersionsSidebarRoot: React.FC<Props> = (props) => {
<X className="size-4" />
</button>
</div>
<PageVersionsSidebarList
<EditorVersionHistorySidebarList
activeVersion={activeVersion}
entityId={entityId}
fetchAllVersions={fetchAllVersions}
isOpen={isOpen}
pageId={pageId}
/>
</div>
);
@@ -4,6 +4,7 @@ export * from "./links";
export * from "./parent";
export * from "./reactions";
export * from "./cycle-select";
export * from "./issue-detail-quick-actions";
export * from "./main-content";
export * from "./module-select";
export * from "./parent-select";
@@ -11,4 +12,4 @@ export * from "./relation-select";
export * from "./root";
export * from "./sidebar";
export * from "./subscription";
export * from "./issue-detail-quick-actions";
export * from "./version-history";
@@ -175,7 +175,7 @@ export const IssueDetailRoot: FC<TIssueDetailRoot> = observer((props) => {
},
path: pathname,
});
} catch (error) {
} catch {
setToast({
type: TOAST_TYPE.ERROR,
title: "Error!",
@@ -204,7 +204,7 @@ export const IssueDetailRoot: FC<TIssueDetailRoot> = observer((props) => {
},
path: pathname,
});
} catch (error) {
} catch {
setToast({
type: TOAST_TYPE.ERROR,
title: "Error!",
@@ -245,7 +245,7 @@ export const IssueDetailRoot: FC<TIssueDetailRoot> = observer((props) => {
},
path: pathname,
});
} catch (error) {
} catch {
captureIssueEvent({
eventName: ISSUE_UPDATED,
payload: { state: "FAILED", element: "Issue detail page" },
@@ -281,7 +281,7 @@ export const IssueDetailRoot: FC<TIssueDetailRoot> = observer((props) => {
},
path: pathname,
});
} catch (error) {
} catch {
captureIssueEvent({
eventName: ISSUE_UPDATED,
payload: { id: issueId, state: "FAILED", element: "Issue detail page" },
@@ -373,7 +373,6 @@ export const IssueDetailRoot: FC<TIssueDetailRoot> = observer((props) => {
</div>
</div>
)}
{/* peek overview */}
<IssuePeekOverview />
</>
@@ -0,0 +1,82 @@
"use client";
import { useEffect, useState } from "react";
import { useParams, useRouter, useSearchParams } from "next/navigation";
// plane editor
import { EditorReadOnlyRefApi, EditorRefApi } from "@plane/editor";
// components
import { EditorVersionHistoryOverlay, IssueVersionEditor } from "@/components/editor";
// hooks
import { useQueryParams } from "@/hooks/use-query-params";
// services
import { IssueVersionService } from "@/services/issue";
const issueVersionService = new IssueVersionService();
type Props = {
disabled: boolean;
editorRef: EditorRefApi;
issueId: string;
readOnlyEditorRef: EditorReadOnlyRefApi;
};
export const IssueVersionHistory: React.FC<Props> = (props) => {
const { disabled, editorRef, issueId, readOnlyEditorRef } = props;
// states
const [isVersionsOverlayOpen, setIsVersionsOverlayOpen] = useState(false);
// search params
const searchParams = useSearchParams();
// params
const { projectId, workspaceSlug } = useParams();
// router
const router = useRouter();
// update query params
const { updateQueryParams } = useQueryParams();
const version = searchParams.get("version");
useEffect(() => {
if (!version) {
setIsVersionsOverlayOpen(false);
return;
}
setIsVersionsOverlayOpen(true);
}, [version]);
const handleCloseVersionsOverlay = () => {
const updatedRoute = updateQueryParams({
paramsToRemove: ["version"],
});
router.push(updatedRoute);
};
const handleRestoreVersion = async (descriptionHTML: string) => {
editorRef?.clearEditor();
editorRef?.setEditorValue(descriptionHTML);
};
const currentVersionDescription = disabled ? readOnlyEditorRef?.getDocument().html : editorRef?.getDocument().html;
return (
<EditorVersionHistoryOverlay
activeVersion={version}
currentVersionDescription={currentVersionDescription ?? null}
editorComponent={IssueVersionEditor}
entityId={issueId}
fetchAllVersions={async (issueId) => {
if (!workspaceSlug || !projectId) return;
return await issueVersionService.fetchAllVersions(workspaceSlug.toString(), projectId.toString(), issueId);
}}
fetchVersionDetails={async (issueId, versionId) => {
if (!workspaceSlug || !projectId) return;
return await issueVersionService.fetchVersionById(
workspaceSlug.toString(),
projectId.toString(),
issueId,
versionId
);
}}
handleRestore={handleRestoreVersion}
isOpen={isVersionsOverlayOpen}
onClose={handleCloseVersionsOverlay}
restoreEnabled={!disabled}
/>
);
};
@@ -8,7 +8,8 @@ import { TPage } from "@plane/types";
// ui
import { setToast, TOAST_TYPE } from "@plane/ui";
// components
import { PageEditorHeaderRoot, PageEditorBody, PageVersionsOverlay, PagesVersionEditor } from "@/components/pages";
import { EditorVersionHistoryOverlay, PageVersionEditor } from "@/components/editor";
import { PageEditorHeaderRoot, PageEditorBody } from "@/components/pages";
// hooks
import { useProjectPages } from "@/hooks/store";
import { useAppRouter } from "@/hooks/use-app-router";
@@ -105,10 +106,11 @@ export const PageRoot = observer((props: TPageRootProps) => {
return (
<>
<PageVersionsOverlay
<EditorVersionHistoryOverlay
activeVersion={version}
currentVersionDescription={currentVersionDescription ?? null}
editorComponent={PagesVersionEditor}
editorComponent={PageVersionEditor}
entityId={page.id ?? ""}
fetchAllVersions={async (pageId) => {
if (!workspaceSlug || !projectId) return;
return await projectPageVersionService.fetchAllVersions(
@@ -129,7 +131,6 @@ export const PageRoot = observer((props: TPageRootProps) => {
handleRestore={handleRestoreVersion}
isOpen={isVersionsOverlayOpen}
onClose={handleCloseVersionsOverlay}
pageId={page.id ?? ""}
restoreEnabled={isContentEditable}
/>
<PageEditorHeaderRoot
+1 -1
View File
@@ -251,7 +251,7 @@ export class Storage {
activeSpan?.setAttributes({
projectId: projectId,
count: response?.total_results,
count: response.total_count,
});
};
+1
View File
@@ -7,4 +7,5 @@ export * from "./issue_attachment.service";
export * from "./issue_activity.service";
export * from "./issue_comment.service";
export * from "./issue_relation.service";
export * from "./issue_version.service";
export * from "./workspace_draft.service";
@@ -0,0 +1,33 @@
// plane types
import { TEditorVersion } from "@plane/types";
// helpers
import { API_BASE_URL } from "@/helpers/common.helper";
// services
import { APIService } from "@/services/api.service";
export class IssueVersionService extends APIService {
constructor() {
super(API_BASE_URL);
}
async fetchAllVersions(workspaceSlug: string, projectId: string, issueId: string): Promise<TEditorVersion[]> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/versions/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
async fetchVersionById(
workspaceSlug: string,
projectId: string,
issueId: string,
versionId: string
): Promise<TEditorVersion> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/versions/${versionId}/`)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;
});
}
}
@@ -1,5 +1,5 @@
// plane types
import { TPageVersion } from "@plane/types";
import { TEditorVersion } from "@plane/types";
// helpers
import { API_BASE_URL } from "@/helpers/common.helper";
// services
@@ -10,7 +10,7 @@ export class ProjectPageVersionService extends APIService {
super(API_BASE_URL);
}
async fetchAllVersions(workspaceSlug: string, projectId: string, pageId: string): Promise<TPageVersion[]> {
async fetchAllVersions(workspaceSlug: string, projectId: string, pageId: string): Promise<TEditorVersion[]> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/${pageId}/versions/`)
.then((response) => response?.data)
.catch((error) => {
@@ -23,7 +23,7 @@ export class ProjectPageVersionService extends APIService {
projectId: string,
pageId: string,
versionId: string
): Promise<TPageVersion> {
): Promise<TEditorVersion> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/${pageId}/versions/${versionId}/`)
.then((response) => response?.data)
.catch((error) => {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "web",
"version": "0.24.0",
"version": "0.23.1",
"private": true,
"scripts": {
"dev": "turbo run develop",
+34 -34
View File
@@ -11952,47 +11952,47 @@ tunnel-agent@^0.6.0:
dependencies:
safe-buffer "^5.0.1"
turbo-darwin-64@2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/turbo-darwin-64/-/turbo-darwin-64-2.3.3.tgz#875975cddf7abdb52b28e9cab234fc73ca001e80"
integrity sha512-bxX82xe6du/3rPmm4aCC5RdEilIN99VUld4HkFQuw+mvFg6darNBuQxyWSHZTtc25XgYjQrjsV05888w1grpaA==
turbo-darwin-64@2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/turbo-darwin-64/-/turbo-darwin-64-2.3.2.tgz#e257f6b7911718b1d45b7fa129506b58e38daf62"
integrity sha512-B1lS/UqjXNsG+kx1uzJNwXMuw2i5wavcyNy8opvSLjfuECdsqQU9B1wPqkSTU+mZjFTJcEfiGKyJ/I2EVk8vdw==
turbo-darwin-arm64@2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/turbo-darwin-arm64/-/turbo-darwin-arm64-2.3.3.tgz#5e85d6dadac6560782bb91081fee56f9cfcd103e"
integrity sha512-DYbQwa3NsAuWkCUYVzfOUBbSUBVQzH5HWUFy2Kgi3fGjIWVZOFk86ss+xsWu//rlEAfYwEmopigsPYSmW4X15A==
turbo-darwin-arm64@2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/turbo-darwin-arm64/-/turbo-darwin-arm64-2.3.2.tgz#96e09af5c710a62196cd313bca83dbbfab84f50f"
integrity sha512-XHeuEdk9tHaw2Bsr3rTzFtZyldeSyagDZkOSPIJ1zioavMjWEFPA75vdgy4j8ns96EBpZMaPXVEnODuEHfiZfQ==
turbo-linux-64@2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/turbo-linux-64/-/turbo-linux-64-2.3.3.tgz#634f2053cff6ff056bec7f307c2fb4dd9a2bc86f"
integrity sha512-eHj9OIB0dFaP6BxB88jSuaCLsOQSYWBgmhy2ErCu6D2GG6xW3b6e2UWHl/1Ho9FsTg4uVgo4DB9wGsKa5erjUA==
turbo-linux-64@2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/turbo-linux-64/-/turbo-linux-64-2.3.2.tgz#7508f591c6874fdd6fab54658f55489363c20b0a"
integrity sha512-oKDsO5+flqpPx5tNLFGVUYpJ/sBc3KvaGpyNzXl2u3epzyafgblFKWMG5YsSiU1ruouPpcC6YG5SN5chA7Abfg==
turbo-linux-arm64@2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/turbo-linux-arm64/-/turbo-linux-arm64-2.3.3.tgz#284e26825f5d692bffb5b126a9aeccaae6a4533b"
integrity sha512-NmDE/NjZoDj1UWBhMtOPmqFLEBKhzGS61KObfrDEbXvU3lekwHeoPvAMfcovzswzch+kN2DrtbNIlz+/rp8OCg==
turbo-linux-arm64@2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/turbo-linux-arm64/-/turbo-linux-arm64-2.3.2.tgz#15109394c077374fbe7657129c08b75ea5008c1c"
integrity sha512-luyvTl3wQ1hF+ljK7ljH4TL7rg4pmx5pQ2mzvfMvPo5eaLuKr/tImmbdH6/vr56iffUIISkIsLVhVxgZeAsUOw==
turbo-windows-64@2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/turbo-windows-64/-/turbo-windows-64-2.3.3.tgz#2900ac2c00d9609bc480d90564a98ca1cc7f4b17"
integrity sha512-O2+BS4QqjK3dOERscXqv7N2GXNcqHr9hXumkMxDj/oGx9oCatIwnnwx34UmzodloSnJpgSqjl8iRWiY65SmYoQ==
turbo-windows-64@2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/turbo-windows-64/-/turbo-windows-64-2.3.2.tgz#c15d3aa097b7396432360103b9e74991e3bb6cee"
integrity sha512-yw7BnTU5cE7GdUnZEW3jIAI98hh4dcWk+Jwza8X7CXpxpill2zteq7VPf+a/B3o/xm+oVXzLmP83YP91Bm0SaA==
turbo-windows-arm64@2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/turbo-windows-arm64/-/turbo-windows-arm64-2.3.3.tgz#395508cdf6b351d7dd324fb0b318c1b2cf1d66dd"
integrity sha512-dW4ZK1r6XLPNYLIKjC4o87HxYidtRRcBeo/hZ9Wng2XM/MqqYkAyzJXJGgRMsc0MMEN9z4+ZIfnSNBrA0b08ag==
turbo-windows-arm64@2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/turbo-windows-arm64/-/turbo-windows-arm64-2.3.2.tgz#9c03ea846d706f9cf92e50ade43f8f67adf7d744"
integrity sha512-Hgp6V7jaIYlDcy5xpKN+XXyYCf5afT690GmXcEsMoUawd5dStvZe0QHWcGxuqho497BAlx0XGAWftm0KelNePA==
turbo@^2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/turbo/-/turbo-2.3.3.tgz#70736263c75f7c0c501278214dee49859e1c7fcd"
integrity sha512-DUHWQAcC8BTiUZDRzAYGvpSpGLiaOQPfYXlCieQbwUvmml/LRGIe3raKdrOPOoiX0DYlzxs2nH6BoWJoZrj8hA==
turbo@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/turbo/-/turbo-2.3.2.tgz#e914e7942b948f020e7629052b759d7936b9838c"
integrity sha512-vCJPoy8/3KkqY3W0cX2nrwhmtBQSZhEyrVgeJ4NlEXwGxu5vNRQDyV6se5VVAQMwfBsBJswlo87B7ai7Dr1MpQ==
optionalDependencies:
turbo-darwin-64 "2.3.3"
turbo-darwin-arm64 "2.3.3"
turbo-linux-64 "2.3.3"
turbo-linux-arm64 "2.3.3"
turbo-windows-64 "2.3.3"
turbo-windows-arm64 "2.3.3"
turbo-darwin-64 "2.3.2"
turbo-darwin-arm64 "2.3.2"
turbo-linux-64 "2.3.2"
turbo-linux-arm64 "2.3.2"
turbo-windows-64 "2.3.2"
turbo-windows-arm64 "2.3.2"
tween-functions@^1.2.0:
version "1.2.0"