Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement: High Performance MobX Integration for Pages ✈︎ #3397

Merged
merged 43 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
dec18e4
fix: removed parameters `workspace`, `project` & `id` from the patch …
henit-chobisa Jan 10, 2024
1e1b9dc
feat: modified components to work with new pages hooks
henit-chobisa Jan 11, 2024
9fe60e5
feat: modified stores
henit-chobisa Jan 11, 2024
85df661
feat: modified initial component
henit-chobisa Jan 11, 2024
876460d
Merge branch 'develop' into fix/page-store-implementation
henit-chobisa Jan 11, 2024
3d4567e
feat: component implementation changes
henit-chobisa Jan 11, 2024
e853daf
feat: store implementation
henit-chobisa Jan 11, 2024
fe18462
refactor pages store
Jan 11, 2024
0f15e72
feat: updated page store to perform async operations faster
henit-chobisa Jan 12, 2024
20f85b3
fix: added types for archive and restore pages
henit-chobisa Jan 12, 2024
0eba5c7
feat: implemented archive and restore pages
henit-chobisa Jan 12, 2024
1b0f2b1
fix: page creating twice when form submit
henit-chobisa Jan 12, 2024
ecf97c0
feat: updated create-page-modal
henit-chobisa Jan 16, 2024
bd5898f
feat: updated page form and delete page modal
henit-chobisa Jan 16, 2024
8ced039
fix: create page modal not updating isSubmitted prop
henit-chobisa Jan 16, 2024
65d50a5
feat: list items and list view refactored for pages
henit-chobisa Jan 16, 2024
934ecc7
feat: refactored project-page-store for inserting computed pagesids
henit-chobisa Jan 16, 2024
1734a60
chore: renamed project pages hook
henit-chobisa Jan 16, 2024
ee3e3c6
feat: added favourite pages implementation
henit-chobisa Jan 16, 2024
fe54b66
fix: implemented store for archived pages
henit-chobisa Jan 16, 2024
997e414
fix: project page store for recent pages
henit-chobisa Jan 16, 2024
43946d5
fix: issue suggestions breaking pages
henit-chobisa Jan 16, 2024
4fb2ca4
fix: issue embeds and suggestions breaking
henit-chobisa Jan 17, 2024
45ba1ba
feat: implemented page store and project page store in page editor
henit-chobisa Jan 17, 2024
fa1da63
chore: lock file changes
henit-chobisa Jan 17, 2024
ac2c321
Merge branch 'develop' into fix/page-store-implementation
henit-chobisa Jan 17, 2024
3901a38
fix: modified page details header to catch mobx updates instead of sw…
henit-chobisa Jan 17, 2024
c815d13
fix: modified usePage hook to fetch page details when reloaded direct…
henit-chobisa Jan 17, 2024
09d1f6a
fix: fixed deleting pages
henit-chobisa Jan 17, 2024
4b3c014
fix: removed render on props changed
henit-chobisa Jan 17, 2024
c7111c1
feat: implemented page store inside page details
henit-chobisa Jan 17, 2024
7ba76d8
fix: role change in pages archives
henit-chobisa Jan 17, 2024
e1c5071
fix: rerending of pages on tab change
henit-chobisa Jan 17, 2024
af3bbbf
fix: reimplementation of peek overview inside pages
henit-chobisa Jan 17, 2024
99f5383
chore: typo fixes
henit-chobisa Jan 17, 2024
f5d8217
fix: issue suggestion widget selecting wrong issues on click
henit-chobisa Jan 17, 2024
3b9123b
feat: added labels in pages
henit-chobisa Jan 17, 2024
3518120
fix: deepsource errors fixed
henit-chobisa Jan 17, 2024
0803c44
fix: build errors
henit-chobisa Jan 17, 2024
4ae67be
fix: review comments
henit-chobisa Jan 18, 2024
88f116e
fix: removed swr hooks from the `usePage` store hook and refactored `…
henit-chobisa Jan 18, 2024
652b1b7
fix: resolved reviewed comments
henit-chobisa Jan 19, 2024
2dad891
Merge branch 'develop' into fix/page-store-implementation
henit-chobisa Jan 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 10 additions & 21 deletions apiserver/plane/app/views/page.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,25 @@
# Python imports
from datetime import timedelta, date, datetime
from datetime import date, datetime, timedelta

# Django imports
from django.db import connection
from django.db.models import Exists, OuterRef, Q
from django.utils import timezone
from django.utils.decorators import method_decorator
from django.views.decorators.gzip import gzip_page

# Third party imports
from rest_framework import status
from rest_framework.response import Response

# Module imports
from .base import BaseViewSet, BaseAPIView
from plane.app.permissions import ProjectEntityPermission
from plane.db.models import (
Page,
PageFavorite,
Issue,
IssueAssignee,
IssueActivity,
PageLog,
ProjectMember,
)
from plane.app.serializers import (
PageSerializer,
PageFavoriteSerializer,
PageLogSerializer,
IssueLiteSerializer,
SubPageSerializer,
)
from plane.app.serializers import (IssueLiteSerializer, PageFavoriteSerializer,
PageLogSerializer, PageSerializer,
SubPageSerializer)
from plane.db.models import (Issue, IssueActivity, IssueAssignee, Page,
PageFavorite, PageLog, ProjectMember)

# Module imports
from .base import BaseAPIView, BaseViewSet


def unarchive_archive_page_and_descendants(page_id, archived_at):
Expand Down Expand Up @@ -175,7 +164,7 @@ def archive(self, request, slug, project_id, page_id):
project_id=project_id,
member=request.user,
is_active=True,
role__gt=20,
role__gte=20,
).exists()
or request.user.id != page.owned_by_id
):
Expand Down
1 change: 1 addition & 0 deletions packages/editor/document-editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"@plane/editor-core": "*",
"@plane/editor-extensions": "*",
"@plane/ui": "*",
"@tippyjs/react": "^4.2.6",
"@tiptap/core": "^2.1.13",
"@tiptap/extension-placeholder": "^2.1.13",
"@tiptap/pm": "^2.1.13",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {

type IPageRenderer = {
documentDetails: DocumentDetails;
updatePageTitle: (title: string) => Promise<void>;
updatePageTitle: (title: string) => void;
editor: Editor;
onActionCompleteHandler: (action: {
title: string;
Expand All @@ -30,18 +30,6 @@ type IPageRenderer = {
readonly: boolean;
};

const debounce = (func: (...args: any[]) => void, wait: number) => {
let timeout: NodeJS.Timeout | null = null;
return function executedFunction(...args: any[]) {
const later = () => {
if (timeout) clearTimeout(timeout);
func(...args);
};
if (timeout) clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
};

export const PageRenderer = (props: IPageRenderer) => {
const { documentDetails, editor, editorClassNames, editorContentCustomClassNames, updatePageTitle, readonly } = props;

Expand All @@ -64,11 +52,9 @@ export const PageRenderer = (props: IPageRenderer) => {

const { getFloatingProps } = useInteractions([dismiss]);

const debouncedUpdatePageTitle = debounce(updatePageTitle, 300);

const handlePageTitleChange = (title: string) => {
setPagetitle(title);
debouncedUpdatePageTitle(title);
updatePageTitle(title);
};

const [cleanup, setcleanup] = useState(() => () => {});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const DocumentEditorExtensions = (
.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>"
"<p class='text-sm bg-gray-300 w-fit pl-3 pr-3 pt-1 pb-1 rounded shadow-sm'>#issue_</p>\n"
)
.run();
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const IssueSuggestions = (suggestions: any[]) => {
title: suggestion.name,
priority: suggestion.priority.toString(),
identifier: `${suggestion.project_detail.identifier}-${suggestion.sequence_id}`,
state: suggestion.state_detail.name,
state: suggestion.state_detail && suggestion.state_detail.name ? suggestion.state_detail.name : "Todo",
command: ({ editor, range }) => {
editor
.chain()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export const IssueEmbedSuggestions = Extension.create({
addOptions() {
return {
suggestion: {
char: "#issue_",
allowSpaces: true,
command: ({ editor, range, props }: { editor: Editor; range: Range; props: any }) => {
props.command({ editor, range });
},
Expand All @@ -18,11 +20,8 @@ export const IssueEmbedSuggestions = Extension.create({
addProseMirrorPlugins() {
return [
Suggestion({
char: "#issue_",
pluginKey: new PluginKey("issue-embed-suggestions"),
editor: this.editor,
allowSpaces: true,

...this.options.suggestion,
}),
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const IssueSuggestionList = ({
const commandListContainer = useRef<HTMLDivElement>(null);

useEffect(() => {
let newDisplayedItems: { [key: string]: IssueSuggestionProps[] } = {};
const newDisplayedItems: { [key: string]: IssueSuggestionProps[] } = {};
let totalLength = 0;
sections.forEach((section) => {
newDisplayedItems[section] = items.filter((item) => item.state === section).slice(0, 5);
Expand All @@ -65,8 +65,8 @@ const IssueSuggestionList = ({
}, [items]);

const selectItem = useCallback(
(index: number) => {
const item = displayedItems[currentSection][index];
(section: string, index: number) => {
const item = displayedItems[section][index];
if (item) {
command(item);
}
Expand All @@ -87,6 +87,7 @@ const IssueSuggestionList = ({
setSelectedIndex(
(selectedIndex + displayedItems[currentSection].length - 1) % displayedItems[currentSection].length
);
e.stopPropagation();
return true;
}
if (e.key === "ArrowDown") {
Expand All @@ -101,17 +102,20 @@ const IssueSuggestionList = ({
[currentSection]: [...prevItems[currentSection], ...nextItems],
}));
}
e.stopPropagation();
return true;
}
if (e.key === "Enter") {
selectItem(selectedIndex);
selectItem(currentSection, selectedIndex);
e.stopPropagation();
return true;
}
if (e.key === "Tab") {
const currentSectionIndex = sections.indexOf(currentSection);
const nextSectionIndex = (currentSectionIndex + 1) % sections.length;
setCurrentSection(sections[nextSectionIndex]);
setSelectedIndex(0);
e.stopPropagation();
return true;
}
return false;
Expand Down Expand Up @@ -172,7 +176,7 @@ const IssueSuggestionList = ({
}
)}
key={item.identifier}
onClick={() => selectItem(index)}
onClick={() => selectItem(section, index)}
>
<h5 className="whitespace-nowrap text-xs text-custom-text-300">{item.identifier}</h5>
<PriorityIcon priority={item.priority} />
Expand All @@ -195,7 +199,7 @@ export const IssueListRenderer = () => {
let popup: any | null = null;

return {
onStart: (props: { editor: Editor; clientRect: DOMRect }) => {
onStart: (props: { editor: Editor; clientRect?: (() => DOMRect | null) | null }) => {
component = new ReactRenderer(IssueSuggestionList, {
props,
// @ts-ignore
Expand All @@ -210,10 +214,10 @@ export const IssueListRenderer = () => {
showOnCreate: true,
interactive: true,
trigger: "manual",
placement: "right",
placement: "bottom-start",
});
},
onUpdate: (props: { editor: Editor; clientRect: DOMRect }) => {
onUpdate: (props: { editor: Editor; clientRect?: (() => DOMRect | null) | null }) => {
component?.updateProps(props);

popup &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ export const IssueWidgetCard = (props) => {
setIssueDetails(issue);
setLoading(0);
})
.catch((error) => {
console.log(error);
.catch(() => {
setLoading(-1);
});
}, []);
Expand All @@ -30,7 +29,9 @@ export const IssueWidgetCard = (props) => {
{loading == 0 ? (
<div
onClick={completeIssueEmbedAction}
className="w-full cursor-pointer space-y-2 rounded-md border-[0.5px] border-custom-border-200 p-3 shadow-custom-shadow-2xs"
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}
Expand Down
4 changes: 2 additions & 2 deletions packages/editor/document-editor/src/ui/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ interface IDocumentEditor {
// document info
documentDetails: DocumentDetails;
value: string;
rerenderOnPropsChange: {
rerenderOnPropsChange?: {
id: string;
description_html: string;
};
Expand All @@ -39,7 +39,7 @@ interface IDocumentEditor {
setIsSubmitting?: (isSubmitting: "submitting" | "submitted" | "saved") => void;
setShouldShowAlert?: (showAlert: boolean) => void;
forwardedRef?: any;
updatePageTitle: (title: string) => Promise<void>;
updatePageTitle: (title: string) => void;
debouncedUpdatesEnabled?: boolean;
isSubmitting: "submitting" | "submitted" | "saved";

Expand Down
15 changes: 2 additions & 13 deletions web/components/headers/page-details.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
import { FC } from "react";
import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
import useSWR from "swr";
import { FileText, Plus } from "lucide-react";
// hooks
import { useApplication, useProject } from "hooks/store";
// services
import { PageService } from "services/page.service";
import { useApplication, usePage, useProject } from "hooks/store";
// ui
import { Breadcrumbs, Button } from "@plane/ui";
// helpers
import { renderEmoji } from "helpers/emoji.helper";
// fetch-keys
import { PAGE_DETAILS } from "constants/fetch-keys";

export interface IPagesHeaderProps {
showButton?: boolean;
}
const pageService = new PageService();

export const PageDetailsHeader: FC<IPagesHeaderProps> = observer((props) => {
const { showButton = false } = props;
Expand All @@ -28,12 +22,7 @@ export const PageDetailsHeader: FC<IPagesHeaderProps> = observer((props) => {
const { commandPalette: commandPaletteStore } = useApplication();
const { currentProjectDetails } = useProject();

const { data: pageDetails } = useSWR(
workspaceSlug && currentProjectDetails?.id && pageId ? PAGE_DETAILS(pageId as string) : null,
workspaceSlug && currentProjectDetails?.id
? () => pageService.getPageDetails(workspaceSlug as string, currentProjectDetails.id, pageId as string)
: null
);
const pageDetails = usePage(pageId as string);

return (
<div className="relative z-10 flex h-[3.75rem] w-full flex-shrink-0 flex-row items-center justify-between gap-x-2 gap-y-4 border-b border-custom-border-200 bg-custom-sidebar-background-100 p-4">
Expand Down
Loading
Loading