mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
style: pages edit history components
This commit is contained in:
parent
41d8005f0b
commit
5f24c0f838
@ -51,7 +51,7 @@
|
||||
"jsx-dom-cjs": "^8.0.3",
|
||||
"linkifyjs": "^4.1.3",
|
||||
"lowlight": "^3.0.0",
|
||||
"lucide-react": "^0.294.0",
|
||||
"lucide-react": "^0.368.0",
|
||||
"prosemirror-codemark": "^0.4.2",
|
||||
"react-moveable": "^0.54.2",
|
||||
"tailwind-merge": "^1.14.0",
|
||||
|
@ -36,7 +36,7 @@
|
||||
"@tiptap/core": "^2.1.13",
|
||||
"@tiptap/pm": "^2.1.13",
|
||||
"@tiptap/suggestion": "^2.1.13",
|
||||
"lucide-react": "^0.309.0",
|
||||
"lucide-react": "^0.368.0",
|
||||
"react-popper": "^2.3.0",
|
||||
"tippy.js": "^6.3.7",
|
||||
"uuid": "^9.0.1"
|
||||
|
@ -34,7 +34,7 @@
|
||||
"@tiptap/pm": "^2.1.13",
|
||||
"@tiptap/react": "^2.1.13",
|
||||
"@tiptap/suggestion": "^2.1.13",
|
||||
"lucide-react": "^0.294.0",
|
||||
"lucide-react": "^0.368.0",
|
||||
"tippy.js": "^6.3.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -32,7 +32,7 @@
|
||||
"@plane/editor-core": "*",
|
||||
"@plane/editor-extensions": "*",
|
||||
"@tiptap/core": "^2.1.13",
|
||||
"lucide-react": "^0.294.0"
|
||||
"lucide-react": "^0.368.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "18.15.3",
|
||||
|
@ -29,7 +29,7 @@
|
||||
"dotenv": "^16.3.1",
|
||||
"js-cookie": "^3.0.1",
|
||||
"lowlight": "^2.9.0",
|
||||
"lucide-react": "^0.294.0",
|
||||
"lucide-react": "^0.368.0",
|
||||
"mobx": "^6.10.0",
|
||||
"mobx-react-lite": "^4.0.3",
|
||||
"next": "^14.0.3",
|
||||
|
2
web/components/pages/edit-history/index.ts
Normal file
2
web/components/pages/edit-history/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from "./main-content";
|
||||
export * from "./sidebar";
|
32
web/components/pages/edit-history/main-content.tsx
Normal file
32
web/components/pages/edit-history/main-content.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import { useRef } from "react";
|
||||
// editor
|
||||
import { DocumentReadOnlyEditorWithRef, EditorRefApi } from "@plane/document-editor";
|
||||
// hooks
|
||||
import { useMention } from "@/hooks/store";
|
||||
|
||||
type Props = {
|
||||
projectId: string;
|
||||
workspaceSlug: string;
|
||||
};
|
||||
|
||||
export const PageEditHistoryMainContent: React.FC<Props> = (props) => {
|
||||
const { projectId, workspaceSlug } = props;
|
||||
// refs
|
||||
const editorRef = useRef<EditorRefApi>(null);
|
||||
// store hooks
|
||||
const { mentionHighlights } = useMention({
|
||||
workspaceSlug,
|
||||
projectId,
|
||||
});
|
||||
|
||||
return (
|
||||
<DocumentReadOnlyEditorWithRef
|
||||
ref={editorRef}
|
||||
initialValue={"<p>Page edit history</p>"}
|
||||
containerClassName="p-5 pl-10 border-none"
|
||||
mentionHandler={{
|
||||
highlights: mentionHighlights,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
26
web/components/pages/edit-history/sidebar.tsx
Normal file
26
web/components/pages/edit-history/sidebar.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import { cn } from "@/helpers/common.helper";
|
||||
|
||||
type Props = {
|
||||
activeVersionId: string;
|
||||
};
|
||||
|
||||
export const PageEditHistorySidebar: React.FC<Props> = (props) => {
|
||||
const {} = props;
|
||||
|
||||
return (
|
||||
<>
|
||||
{Array.from({ length: 10 }).map((_, index) => (
|
||||
<button
|
||||
key={index}
|
||||
type="button"
|
||||
className={cn("block w-full py-1 px-3 rounded hover:bg-custom-background-90 text-left", {
|
||||
// "bg-custom-background-90": version.id === activeVersionId,
|
||||
})}
|
||||
>
|
||||
<p className="text-sm">{index}. Today at 1:28 PM</p>
|
||||
<span className="text-custom-text-400 text-sm">Aaryan Khandelwal</span>
|
||||
</button>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
@ -1,9 +1,12 @@
|
||||
import { useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
import { Clipboard, Copy, Link, Lock } from "lucide-react";
|
||||
import { Clipboard, Copy, History, Link, Lock } from "lucide-react";
|
||||
// document editor
|
||||
import { EditorReadOnlyRefApi, EditorRefApi } from "@plane/document-editor";
|
||||
// ui
|
||||
import { ArchiveIcon, CustomMenu, TOAST_TYPE, ToggleSwitch, setToast } from "@plane/ui";
|
||||
// components
|
||||
import { PageEditHistoryModal } from "@/components/pages";
|
||||
// helpers
|
||||
import { copyTextToClipboard, copyUrlToClipboard } from "@/helpers/string.helper";
|
||||
// hooks
|
||||
@ -17,8 +20,18 @@ type Props = {
|
||||
pageStore: IPageStore;
|
||||
};
|
||||
|
||||
type TMenuItems = {
|
||||
key: string;
|
||||
action: () => void;
|
||||
label: string;
|
||||
icon: React.FC<any>;
|
||||
shouldRender: boolean;
|
||||
};
|
||||
|
||||
export const PageOptionsDropdown: React.FC<Props> = observer((props) => {
|
||||
const { editorRef, handleDuplicatePage, pageStore } = props;
|
||||
// states
|
||||
const [editHistoryModal, setEditHistoryModal] = useState(false);
|
||||
// store values
|
||||
const {
|
||||
archive,
|
||||
@ -73,13 +86,7 @@ export const PageOptionsDropdown: React.FC<Props> = observer((props) => {
|
||||
);
|
||||
|
||||
// menu items list
|
||||
const MENU_ITEMS: {
|
||||
key: string;
|
||||
action: () => void;
|
||||
label: string;
|
||||
icon: React.FC<any>;
|
||||
shouldRender: boolean;
|
||||
}[] = [
|
||||
const PAGE_ACTIONS: TMenuItems[] = [
|
||||
{
|
||||
key: "copy-markdown",
|
||||
action: () => {
|
||||
@ -148,28 +155,52 @@ export const PageOptionsDropdown: React.FC<Props> = observer((props) => {
|
||||
},
|
||||
];
|
||||
|
||||
const EXTRA_OPTIONS: TMenuItems[] = [
|
||||
{
|
||||
key: "edit-history",
|
||||
action: () => setEditHistoryModal(true),
|
||||
label: "View edit history",
|
||||
icon: History,
|
||||
shouldRender: true,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<CustomMenu maxHeight="md" placement="bottom-start" verticalEllipsis closeOnSelect>
|
||||
<CustomMenu.MenuItem
|
||||
className="flex w-full items-center justify-between gap-2"
|
||||
onClick={() =>
|
||||
updateViewProps({
|
||||
full_width: !view_props?.full_width,
|
||||
})
|
||||
}
|
||||
>
|
||||
Full width
|
||||
<ToggleSwitch value={!!view_props?.full_width} onChange={() => {}} />
|
||||
</CustomMenu.MenuItem>
|
||||
{MENU_ITEMS.map((item) => {
|
||||
if (!item.shouldRender) return null;
|
||||
return (
|
||||
<CustomMenu.MenuItem key={item.key} onClick={item.action} className="flex items-center gap-2">
|
||||
<item.icon className="h-3 w-3" />
|
||||
<div className="text-custom-text-300">{item.label}</div>
|
||||
</CustomMenu.MenuItem>
|
||||
);
|
||||
})}
|
||||
</CustomMenu>
|
||||
<>
|
||||
<PageEditHistoryModal isOpen={editHistoryModal} onClose={() => setEditHistoryModal(false)} />
|
||||
<CustomMenu maxHeight="lg" placement="bottom-start" verticalEllipsis closeOnSelect>
|
||||
<CustomMenu.MenuItem
|
||||
className="flex w-full items-center justify-between gap-2"
|
||||
onClick={() =>
|
||||
updateViewProps({
|
||||
full_width: !view_props?.full_width,
|
||||
})
|
||||
}
|
||||
>
|
||||
Full width
|
||||
<ToggleSwitch value={!!view_props?.full_width} onChange={() => {}} />
|
||||
</CustomMenu.MenuItem>
|
||||
<hr className="my-2 border-custom-border-200" />
|
||||
{PAGE_ACTIONS.map((item) => {
|
||||
if (!item.shouldRender) return null;
|
||||
return (
|
||||
<CustomMenu.MenuItem key={item.key} onClick={item.action} className="flex items-center gap-2">
|
||||
<item.icon className="h-3 w-3" />
|
||||
<span>{item.label}</span>
|
||||
</CustomMenu.MenuItem>
|
||||
);
|
||||
})}
|
||||
<hr className="my-2 border-custom-border-200" />
|
||||
{EXTRA_OPTIONS.map((item) => {
|
||||
if (!item.shouldRender) return null;
|
||||
return (
|
||||
<CustomMenu.MenuItem key={item.key} onClick={item.action} className="flex items-center gap-2">
|
||||
<item.icon className="h-3 w-3" />
|
||||
<span>{item.label}</span>
|
||||
</CustomMenu.MenuItem>
|
||||
);
|
||||
})}
|
||||
</CustomMenu>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
export * from "./dropdowns";
|
||||
export * from "./edit-history";
|
||||
export * from "./editor";
|
||||
export * from "./header";
|
||||
export * from "./list";
|
||||
|
81
web/components/pages/modals/edit-history-modal.tsx
Normal file
81
web/components/pages/modals/edit-history-modal.tsx
Normal file
@ -0,0 +1,81 @@
|
||||
import React from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import { CircleHelp } from "lucide-react";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
// ui
|
||||
import { Button } from "@plane/ui";
|
||||
// components
|
||||
import { PageEditHistoryMainContent, PageEditHistorySidebar } from "@/components/pages";
|
||||
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
};
|
||||
|
||||
export const PageEditHistoryModal: React.FC<Props> = (props) => {
|
||||
const { isOpen, onClose } = props;
|
||||
// router
|
||||
const router = useRouter();
|
||||
const { projectId, workspaceSlug } = router.query;
|
||||
|
||||
const handleClose = () => {
|
||||
onClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<Transition.Root show={isOpen} as={React.Fragment}>
|
||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<div className="fixed inset-0 bg-custom-backdrop transition-opacity" />
|
||||
</Transition.Child>
|
||||
|
||||
<div className="fixed inset-0 z-20 overflow-y-auto">
|
||||
<div className="h-full w-full grid place-items-center overflow-hidden">
|
||||
<Transition.Child
|
||||
as={React.Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
>
|
||||
<Dialog.Panel className="size-4/5 bg-custom-background-100 border border-custom-border-200 shadow-custom-shadow-md rounded-lg overflow-hidden">
|
||||
<div className="h-full w-full grid grid-cols-5 overflow-hidden">
|
||||
<div className="h-full col-span-4">
|
||||
<PageEditHistoryMainContent
|
||||
projectId={projectId?.toString() ?? ""}
|
||||
workspaceSlug={workspaceSlug?.toString() ?? ""}
|
||||
/>
|
||||
</div>
|
||||
<div className="h-full w-full flex flex-col divide-y divide-custom-border-200 border-l border-custom-border-200 overflow-hidden">
|
||||
<div className="h-full p-1 overflow-y-scroll vertical-scrollbar scrollbar-sm">
|
||||
<PageEditHistorySidebar activeVersionId="" />
|
||||
</div>
|
||||
<div className="py-3 px-4">
|
||||
<Button variant="primary" size="sm">
|
||||
Restore version
|
||||
</Button>
|
||||
</div>
|
||||
<div className="py-3 px-4 flex items-center gap-2 text-custom-text-400 text-sm">
|
||||
<CircleHelp className="h-3 w-3" />
|
||||
Learn about page history
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</Transition.Child>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</Transition.Root>
|
||||
);
|
||||
};
|
@ -1,3 +1,4 @@
|
||||
export * from "./create-page-modal";
|
||||
export * from "./delete-page-modal";
|
||||
export * from "./edit-history-modal";
|
||||
export * from "./page-form";
|
||||
|
10
yarn.lock
10
yarn.lock
@ -5893,16 +5893,6 @@ lru-cache@^6.0.0:
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484"
|
||||
integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==
|
||||
|
||||
lucide-react@^0.294.0:
|
||||
version "0.294.0"
|
||||
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.294.0.tgz#dc406e1e7e2f722cf93218fe5b31cf3c95778817"
|
||||
integrity sha512-V7o0/VECSGbLHn3/1O67FUgBwWB+hmzshrgDVRJQhMh8uj5D3HBuIvhuAmQTtlupILSplwIZg5FTc4tTKMA2SA==
|
||||
|
||||
lucide-react@^0.309.0:
|
||||
version "0.309.0"
|
||||
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.309.0.tgz#7369893cb4b074a0a0b1d3acdc6fd9a8bdb5add1"
|
||||
integrity sha512-zNVPczuwFrCfksZH3zbd1UDE6/WYhYAdbe2k7CImVyPAkXLgIwbs6eXQ4loigqDnUFjyFYCI5jZ1y10Kqal0dg==
|
||||
|
||||
lucide-react@^0.368.0:
|
||||
version "0.368.0"
|
||||
resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.368.0.tgz#3c0ee63f4f7d30ae63b621b2b8f04f9e409ee6e7"
|
||||
|
Loading…
Reference in New Issue
Block a user