Compare commits

..

6 Commits

Author SHA1 Message Date
Aaryan Khandelwal 2e92f4d58b chore: update loader init logic 2024-11-22 14:20:50 +05:30
Aaryan Khandelwal e37db8d8f4 dev: pages trash 2024-11-22 13:31:34 +05:30
pablohashescobar ca91d5909b chore: formatting errors 2024-11-20 13:00:13 +05:30
pablohashescobar 3bea2e8d1b chore: fix instance apis 2024-11-20 12:35:13 +05:30
sriram veeraghanta 1325064676 fix: typo and naming conventions 2024-11-20 00:32:30 +05:30
sriram veeraghanta a01a371767 fix: typo fixes 2024-11-20 00:00:04 +05:30
36 changed files with 183 additions and 149 deletions
+5 -9
View File
@@ -262,7 +262,7 @@ class PageViewSet(BaseViewSet):
status=status.HTTP_200_OK,
)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
@allow_permission([ROLE.ADMIN], model=Page, creator=True)
def lock(self, request, slug, project_id, pk):
page = Page.objects.filter(
pk=pk, workspace__slug=slug, projects__id=project_id
@@ -272,7 +272,7 @@ class PageViewSet(BaseViewSet):
page.save()
return Response(status=status.HTTP_204_NO_CONTENT)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
@allow_permission([ROLE.ADMIN], model=Page, creator=True)
def unlock(self, request, slug, project_id, pk):
page = Page.objects.filter(
pk=pk, workspace__slug=slug, projects__id=project_id
@@ -283,7 +283,7 @@ class PageViewSet(BaseViewSet):
return Response(status=status.HTTP_204_NO_CONTENT)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
@allow_permission([ROLE.ADMIN], model=Page, creator=True)
def access(self, request, slug, project_id, pk):
access = request.data.get("access", 0)
page = Page.objects.filter(
@@ -330,7 +330,7 @@ class PageViewSet(BaseViewSet):
pages = PageSerializer(queryset, many=True).data
return Response(pages, status=status.HTTP_200_OK)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
@allow_permission([ROLE.ADMIN], model=Page, creator=True)
def archive(self, request, slug, project_id, pk):
page = Page.objects.get(
pk=pk, workspace__slug=slug, projects__id=project_id
@@ -365,7 +365,7 @@ class PageViewSet(BaseViewSet):
status=status.HTTP_200_OK,
)
@allow_permission([ROLE.ADMIN, ROLE.MEMBER, ROLE.GUEST])
@allow_permission([ROLE.ADMIN], model=Page, creator=True)
def unarchive(self, request, slug, project_id, pk):
page = Page.objects.get(
pk=pk, workspace__slug=slug, projects__id=project_id
@@ -438,7 +438,6 @@ class PageViewSet(BaseViewSet):
class PageFavoriteViewSet(BaseViewSet):
model = UserFavorite
@allow_permission([ROLE.ADMIN, ROLE.MEMBER])
@@ -465,7 +464,6 @@ class PageFavoriteViewSet(BaseViewSet):
class PageLogEndpoint(BaseAPIView):
serializer_class = PageLogSerializer
model = PageLog
@@ -504,7 +502,6 @@ class PageLogEndpoint(BaseAPIView):
class SubPagesEndpoint(BaseAPIView):
@method_decorator(gzip_page)
def get(self, request, slug, project_id, page_id):
pages = (
@@ -522,7 +519,6 @@ class SubPagesEndpoint(BaseAPIView):
class PagesDescriptionViewSet(BaseViewSet):
@allow_permission(
[
ROLE.ADMIN,
@@ -0,0 +1,23 @@
# Third party imports
from celery import shared_task
# Django imports
from django.utils import timezone
# Module imports
from plane.db.models import Page
from plane.utils.exception_logger import log_exception
@shared_task
def delete_pages_from_trash():
try:
# Get all the pages whose archived_at is not null, i.e., they are in the trash
Page.objects.filter(
archived_at__isnull=False,
archived_at__lte=timezone.now() - timezone.timedelta(days=90),
).delete()
return
except Exception as e:
log_exception(e)
return
+4
View File
@@ -40,6 +40,10 @@ app.conf.beat_schedule = {
"task": "plane.bgtasks.api_logs_task.delete_api_logs",
"schedule": crontab(hour=0, minute=0),
},
"check-every-day-to-delete-pages-from-trash": {
"task": "plane.bgtasks.delete_pages_from_trash.delete_pages_from_trash",
"schedule": crontab(hour=0, minute=0),
},
"run-every-6-hours-for-instance-trace": {
"task": "plane.license.bgtasks.tracer.instance_traces",
"schedule": crontab(hour="*/6", minute=0),
@@ -1,9 +1,7 @@
# Generated by Django 4.2.15 on 2024-11-06 08:41
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import uuid
class Migration(migrations.Migration):
@@ -11,9 +11,7 @@ class InstanceSerializer(BaseSerializer):
class Meta:
model = Instance
exclude = [
"license_key",
]
fields = "__all__"
read_only_fields = [
"id",
"email",
+1 -9
View File
@@ -3,7 +3,7 @@ from celery import shared_task
from opentelemetry import trace
# Module imports
from plane.license.models import Instance, InstanceAdmin
from plane.license.models import Instance
from plane.db.models import (
User,
Workspace,
@@ -25,7 +25,6 @@ def instance_traces():
# Check if the instance is registered
instance = Instance.objects.first()
instance_admin = InstanceAdmin.objects.first()
# If instance is None then return
if instance is None:
@@ -74,13 +73,6 @@ def instance_traces():
span.set_attribute("module_issue_count", module_issue_count)
span.set_attribute("page_count", page_count)
if instance_admin:
span.set_attribute("admin_email", instance_admin.user.email)
span.set_attribute(
"admin_name",
f"{instance_admin.user.first_name} {instance_admin.user.last_name}",
)
# Workspace details
for workspace in Workspace.objects.all():
# Count of all models
@@ -9,7 +9,7 @@ from django.utils import timezone
from django.conf import settings
# Module imports
from plane.license.models import Instance, EditiontTypes
from plane.license.models import Instance, InstanceEdition
from plane.license.bgtasks.tracer import instance_traces
@@ -55,7 +55,7 @@ class Command(BaseCommand):
latest_version=payload.get("version"),
last_checked_at=timezone.now(),
is_test=os.environ.get("IS_TEST", "0") == "1",
edition=EditiontTypes.PLANE_CE.value,
edition=InstanceEdition.PLANE_COMMUNITY.value,
)
self.stdout.write(self.style.SUCCESS("Instance registered"))
@@ -69,7 +69,7 @@ class Command(BaseCommand):
instance.current_version = payload.get("version")
instance.latest_version = payload.get("version")
instance.is_test = os.environ.get("IS_TEST", "0") == "1"
instance.edition = EditiontTypes.PLANE_CE.value
instance.edition = InstanceEdition.PLANE_COMMUNITY.value
instance.save()
# Call the instance traces task
@@ -4,28 +4,32 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('license', '0004_changelog_deleted_at_instance_deleted_at_and_more'),
("license", "0004_changelog_deleted_at_instance_deleted_at_and_more"),
]
operations = [
migrations.RenameField(
model_name='instance',
old_name='product',
new_name='edition',
model_name="instance",
old_name="product",
new_name="edition",
),
migrations.RemoveField(
model_name='instance',
name='license_key',
model_name="instance",
name="license_key",
),
migrations.RemoveField(
model_name='instance',
name='user_count',
model_name="instance",
name="user_count",
),
migrations.AddField(
model_name='instance',
name='is_test',
model_name="instance",
name="is_test",
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name="instance",
name="edition",
field=models.CharField(default="PLANE_COMMUNITY", max_length=255),
),
]
+1 -1
View File
@@ -2,5 +2,5 @@ from .instance import (
Instance,
InstanceAdmin,
InstanceConfiguration,
EditiontTypes,
InstanceEdition,
)
+3 -3
View File
@@ -11,8 +11,8 @@ from plane.db.models import BaseModel
ROLE_CHOICES = ((20, "Admin"),)
class EditiontTypes(Enum):
PLANE_CE = "plane-ce"
class InstanceEdition(Enum):
PLANE_COMMUNITY = "PLANE_COMMUNITY"
class Instance(BaseModel):
@@ -23,7 +23,7 @@ class Instance(BaseModel):
current_version = models.CharField(max_length=255)
latest_version = models.CharField(max_length=255, null=True, blank=True)
edition = models.CharField(
max_length=255, default=EditiontTypes.PLANE_CE.value
max_length=255, default=InstanceEdition.PLANE_COMMUNITY.value
)
domain = models.TextField(blank=True)
# Instance specifics
+1
View File
@@ -303,6 +303,7 @@ CELERY_IMPORTS = (
"plane.bgtasks.email_notification_task",
"plane.bgtasks.api_logs_task",
"plane.license.bgtasks.tracer",
"plane.bgtasks.delete_pages_from_trash",
# management tasks
"plane.bgtasks.dummy_data_task",
)
-1
View File
@@ -3,7 +3,6 @@ from django.urls import path
from plane.space.views import (
IntakeIssuePublicViewSet,
IssueVotePublicViewSet,
WorkspaceProjectDeployBoardEndpoint,
)
+1 -1
View File
@@ -23,7 +23,7 @@ export type TPage = {
};
// page filters
export type TPageNavigationTabs = "public" | "private" | "archived";
export type TPageNavigationTabs = "public" | "private" | "trash";
export type TPageFiltersSortKey =
| "name"
@@ -20,7 +20,7 @@ const PageDetailsPage = observer(() => {
const { workspaceSlug, projectId, pageId } = useParams();
// store hooks
const { getPageById } = useProjectPages();
const { fetchPageById } = useProjectPages();
const page = usePage(pageId?.toString() ?? "");
const { id, name } = page;
@@ -28,7 +28,7 @@ const PageDetailsPage = observer(() => {
const { error: pageDetailsError } = useSWR(
workspaceSlug && projectId && pageId ? `PAGE_DETAILS_${pageId}` : null,
workspaceSlug && projectId && pageId
? () => getPageById(workspaceSlug?.toString(), projectId?.toString(), pageId.toString())
? () => fetchPageById(workspaceSlug?.toString(), projectId?.toString(), pageId.toString())
: null,
{
revalidateIfStale: false,
@@ -1,7 +1,8 @@
"use client";
import { useEffect } from "react";
import { observer } from "mobx-react";
import { useParams, useSearchParams } from "next/navigation";
import { useParams, useSearchParams, useRouter } from "next/navigation";
// types
import { TPageNavigationTabs } from "@plane/types";
// components
@@ -12,14 +13,18 @@ import { PagesListRoot, PagesListView } from "@/components/pages";
import { EmptyStateType } from "@/constants/empty-state";
// hooks
import { useProject } from "@/hooks/store";
import { useQueryParams } from "@/hooks/use-query-params";
const ProjectPagesPage = observer(() => {
// router
const router = useRouter();
// params
const { workspaceSlug, projectId } = useParams();
const searchParams = useSearchParams();
const type = searchParams.get("type");
const { workspaceSlug, projectId } = useParams();
// store hooks
const { getProjectById, currentProjectDetails } = useProject();
const { updateQueryParams } = useQueryParams();
// derived values
const project = projectId ? getProjectById(projectId.toString()) : undefined;
const pageTitle = project?.name ? `${project?.name} - Pages` : undefined;
@@ -27,9 +32,21 @@ const ProjectPagesPage = observer(() => {
const currentPageType = (): TPageNavigationTabs => {
const pageType = type?.toString();
if (pageType === "private") return "private";
if (pageType === "archived") return "archived";
if (pageType === "trash") return "trash";
return "public";
};
// update the route to public pages if the type is invalid
useEffect(() => {
const pageType = type?.toString();
if (pageType !== "public" && pageType !== "private" && pageType !== "trash") {
const updatedRoute = updateQueryParams({
paramsToAdd: {
type: "public",
},
});
router.push(updatedRoute);
}
}, [router, type, updateQueryParams]);
if (!workspaceSlug || !projectId) return <></>;
@@ -22,8 +22,8 @@ const pageTabs: { key: TPageNavigationTabs; label: string }[] = [
label: "Private",
},
{
key: "archived",
label: "Archived",
key: "trash",
label: "Trash",
},
];
@@ -2,33 +2,29 @@
import { Loader } from "@plane/ui";
export const PageLoader: React.FC = (props) => {
const {} = props;
return (
<div className="relative w-full h-full flex flex-col">
<div className="px-3 border-b border-custom-border-100 py-3">
<Loader className="relative flex items-center gap-2">
<Loader.Item width="200px" height="30px" />
<div className="relative flex items-center gap-2 ml-auto">
<Loader.Item width="100px" height="30px" />
<Loader.Item width="100px" height="30px" />
export const PageLoader: React.FC = () => (
<div className="relative w-full h-full flex flex-col">
<div className="px-3 border-b border-custom-border-100 py-3">
<Loader className="relative flex items-center gap-2">
<Loader.Item width="200px" height="30px" />
<div className="relative flex items-center gap-2 ml-auto">
<Loader.Item width="100px" height="30px" />
<Loader.Item width="100px" height="30px" />
</div>
</Loader>
</div>
<div>
{Array.from(Array(10)).map((_, index) => (
<Loader key={index} className="relative flex items-center gap-2 p-3 py-4 border-b border-custom-border-100">
<Loader.Item width={`${250 + 10 * Math.floor(Math.random() * 10)}px`} height="22px" />
<div className="ml-auto relative flex items-center gap-2">
<Loader.Item width="60px" height="22px" />
<Loader.Item width="22px" height="22px" />
<Loader.Item width="22px" height="22px" />
<Loader.Item width="22px" height="22px" />
</div>
</Loader>
</div>
<div>
{Array.from(Array(10)).map((i) => (
<Loader key={i} className="relative flex items-center gap-2 p-3 py-4 border-b border-custom-border-100">
<Loader.Item width={`${250 + 10 * Math.floor(Math.random() * 10)}px`} height="22px" />
<div className="ml-auto relative flex items-center gap-2">
<Loader.Item width="60px" height="22px" />
<Loader.Item width="22px" height="22px" />
<Loader.Item width="22px" height="22px" />
<Loader.Item width="22px" height="22px" />
</div>
</Loader>
))}
</div>
))}
</div>
);
};
</div>
);
@@ -32,35 +32,35 @@ export const PagesListMainContent: React.FC<Props> = observer((props) => {
if (loader === "init-loader") return <PageLoader />;
// if no pages exist in the active page type
if (!isAnyPageAvailable || pageIds?.length === 0) {
if (!isAnyPageAvailable) {
return (
<EmptyState
type={EmptyStateType.PROJECT_PAGE}
primaryButtonOnClick={() => {
toggleCreatePageModal({ isOpen: true });
}}
/>
);
}
if (pageType === "public")
return (
<EmptyState
type={EmptyStateType.PROJECT_PAGE_PUBLIC}
primaryButtonOnClick={() => {
toggleCreatePageModal({ isOpen: true, pageAccess: EPageAccess.PUBLIC });
}}
/>
);
if (pageType === "private")
return (
<EmptyState
type={EmptyStateType.PROJECT_PAGE_PRIVATE}
primaryButtonOnClick={() => {
toggleCreatePageModal({ isOpen: true, pageAccess: EPageAccess.PRIVATE });
}}
/>
);
if (pageType === "archived") return <EmptyState type={EmptyStateType.PROJECT_PAGE_ARCHIVED} />;
return (
<div className="size-full">
{!isAnyPageAvailable && (
<EmptyState
type={EmptyStateType.PROJECT_PAGE}
primaryButtonOnClick={() => {
toggleCreatePageModal({ isOpen: true });
}}
/>
)}
{pageType === "public" ? (
<EmptyState
type={EmptyStateType.PROJECT_PAGE_PUBLIC}
primaryButtonOnClick={() => {
toggleCreatePageModal({ isOpen: true, pageAccess: EPageAccess.PUBLIC });
}}
/>
) : pageType === "private" ? (
<EmptyState
type={EmptyStateType.PROJECT_PAGE_PRIVATE}
primaryButtonOnClick={() => {
toggleCreatePageModal({ isOpen: true, pageAccess: EPageAccess.PRIVATE });
}}
/>
) : pageType === "trash" ? (
<EmptyState type={EmptyStateType.PROJECT_PAGE_TRASH} />
) : null}
</div>
);
}
// if no pages match the filter criteria
if (filteredPageIds?.length === 0)
@@ -95,7 +95,7 @@ export class ProjectPageService extends APIService {
});
}
async archive(
async moveToTrash(
workspaceSlug: string,
projectId: string,
pageId: string
@@ -109,7 +109,7 @@ export class ProjectPageService extends APIService {
});
}
async restore(workspaceSlug: string, projectId: string, pageId: string): Promise<void> {
async restoreFromTrash(workspaceSlug: string, projectId: string, pageId: string): Promise<void> {
return this.delete(`/api/workspaces/${workspaceSlug}/projects/${projectId}/pages/${pageId}/archive/`)
.then((response) => response?.data)
.catch((error) => {
+31 -24
View File
@@ -22,7 +22,7 @@ export interface IPage extends TPage {
canCurrentUserDuplicatePage: boolean;
canCurrentUserLockPage: boolean;
canCurrentUserChangeAccess: boolean;
canCurrentUserArchivePage: boolean;
canCurrentUserTrashPage: boolean;
canCurrentUserDeletePage: boolean;
canCurrentUserFavoritePage: boolean;
isContentEditable: boolean;
@@ -38,8 +38,8 @@ export interface IPage extends TPage {
makePrivate: () => Promise<void>;
lock: () => Promise<void>;
unlock: () => Promise<void>;
archive: () => Promise<void>;
restore: () => Promise<void>;
moveToTrash: () => Promise<void>;
restoreFromTrash: () => Promise<void>;
updatePageLogo: (logo_props: TLogoProps) => Promise<void>;
addToFavorites: () => Promise<void>;
removePageFromFavorites: () => Promise<void>;
@@ -132,7 +132,7 @@ export class Page implements IPage {
canCurrentUserDuplicatePage: computed,
canCurrentUserLockPage: computed,
canCurrentUserChangeAccess: computed,
canCurrentUserArchivePage: computed,
canCurrentUserTrashPage: computed,
canCurrentUserDeletePage: computed,
canCurrentUserFavoritePage: computed,
isContentEditable: computed,
@@ -144,8 +144,8 @@ export class Page implements IPage {
makePrivate: action,
lock: action,
unlock: action,
archive: action,
restore: action,
moveToTrash: action,
restoreFromTrash: action,
updatePageLogo: action,
addToFavorites: action,
removePageFromFavorites: action,
@@ -204,9 +204,11 @@ export class Page implements IPage {
};
}
/**
* @description returns true if the current logged in user is the owner of the page
*/
get isCurrentUserOwner() {
const currentUserId = this.store.user.data?.id;
if (!currentUserId) return false;
return this.owned_by === currentUserId;
}
@@ -215,7 +217,6 @@ export class Page implements IPage {
*/
get canCurrentUserEditPage() {
const { workspaceSlug, projectId } = this.store.router;
const currentUserProjectRole = this.store.user.permission.projectPermissionsByWorkspaceSlugAndProjectId(
workspaceSlug?.toString() || "",
projectId?.toString() || ""
@@ -228,7 +229,6 @@ export class Page implements IPage {
*/
get canCurrentUserDuplicatePage() {
const { workspaceSlug, projectId } = this.store.router;
const currentUserProjectRole = this.store.user.permission.projectPermissionsByWorkspaceSlugAndProjectId(
workspaceSlug?.toString() || "",
projectId?.toString() || ""
@@ -240,22 +240,31 @@ export class Page implements IPage {
* @description returns true if the current logged in user can lock the page
*/
get canCurrentUserLockPage() {
return this.isCurrentUserOwner;
const { workspaceSlug, projectId } = this.store.router;
const currentUserProjectRole = this.store.user.permission.projectPermissionsByWorkspaceSlugAndProjectId(
workspaceSlug?.toString() || "",
projectId?.toString() || ""
);
return this.isCurrentUserOwner || currentUserProjectRole === EUserPermissions.ADMIN;
}
/**
* @description returns true if the current logged in user can change the access of the page
*/
get canCurrentUserChangeAccess() {
return this.isCurrentUserOwner;
const { workspaceSlug, projectId } = this.store.router;
const currentUserProjectRole = this.store.user.permission.projectPermissionsByWorkspaceSlugAndProjectId(
workspaceSlug?.toString() || "",
projectId?.toString() || ""
);
return this.isCurrentUserOwner || currentUserProjectRole === EUserPermissions.ADMIN;
}
/**
* @description returns true if the current logged in user can archive the page
* @description returns true if the current logged in user can trash the page
*/
get canCurrentUserArchivePage() {
get canCurrentUserTrashPage() {
const { workspaceSlug, projectId } = this.store.router;
const currentUserProjectRole = this.store.user.permission.projectPermissionsByWorkspaceSlugAndProjectId(
workspaceSlug?.toString() || "",
projectId?.toString() || ""
@@ -268,7 +277,6 @@ export class Page implements IPage {
*/
get canCurrentUserDeletePage() {
const { workspaceSlug, projectId } = this.store.router;
const currentUserProjectRole = this.store.user.permission.projectPermissionsByWorkspaceSlugAndProjectId(
workspaceSlug?.toString() || "",
projectId?.toString() || ""
@@ -281,7 +289,6 @@ export class Page implements IPage {
*/
get canCurrentUserFavoritePage() {
const { workspaceSlug, projectId } = this.store.router;
const currentUserProjectRole = this.store.user.permission.projectPermissionsByWorkspaceSlugAndProjectId(
workspaceSlug?.toString() || "",
projectId?.toString() || ""
@@ -301,11 +308,11 @@ export class Page implements IPage {
projectId?.toString() || ""
);
const isPublic = this.access === EPageAccess.PUBLIC;
const isArchived = this.archived_at;
const isTrashed = this.archived_at;
const isLocked = this.is_locked;
return (
!isArchived &&
!isTrashed &&
!isLocked &&
(isOwner || (isPublic && !!currentUserRole && currentUserRole >= EUserPermissions.MEMBER))
);
@@ -469,12 +476,12 @@ export class Page implements IPage {
};
/**
* @description archive the page
* @description move the page to trash
*/
archive = async () => {
moveToTrash = async () => {
const { workspaceSlug, projectId } = this.store.router;
if (!workspaceSlug || !projectId || !this.id) return undefined;
const response = await this.pageService.archive(workspaceSlug, projectId, this.id);
const response = await this.pageService.moveToTrash(workspaceSlug, projectId, this.id);
runInAction(() => {
this.archived_at = response.archived_at;
});
@@ -482,12 +489,12 @@ export class Page implements IPage {
};
/**
* @description restore the page
* @description restore the page from trash
*/
restore = async () => {
restoreFromTrash = async () => {
const { workspaceSlug, projectId } = this.store.router;
if (!workspaceSlug || !projectId || !this.id) return undefined;
await this.pageService.restore(workspaceSlug, projectId, this.id);
await this.pageService.restoreFromTrash(workspaceSlug, projectId, this.id);
runInAction(() => {
this.archived_at = null;
});
+15 -16
View File
@@ -31,12 +31,8 @@ export interface IProjectPageStore {
updateFilters: <T extends keyof TPageFilters>(filterKey: T, filterValue: TPageFilters[T]) => void;
clearAllFilters: () => void;
// actions
getAllPages: (
workspaceSlug: string,
projectId: string,
pageType: TPageNavigationTabs
) => Promise<TPage[] | undefined>;
getPageById: (workspaceSlug: string, projectId: string, pageId: string) => Promise<TPage | undefined>;
fetchAllPages: (workspaceSlug: string, projectId: string) => Promise<TPage[]>;
fetchPageById: (workspaceSlug: string, projectId: string, pageId: string) => Promise<TPage>;
createPage: (pageData: Partial<TPage>) => Promise<TPage | undefined>;
removePage: (pageId: string) => Promise<void>;
}
@@ -66,8 +62,8 @@ export class ProjectPageStore implements IProjectPageStore {
updateFilters: action,
clearAllFilters: action,
// actions
getAllPages: action,
getPageById: action,
fetchAllPages: action,
fetchPageById: action,
createPage: action,
removePage: action,
});
@@ -154,13 +150,14 @@ export class ProjectPageStore implements IProjectPageStore {
/**
* @description fetch all the pages
*/
getAllPages = async (workspaceSlug: string, projectId: string, pageType: TPageNavigationTabs) => {
fetchAllPages = async (workspaceSlug: string, projectId: string) => {
try {
if (!workspaceSlug || !projectId) return undefined;
if (!workspaceSlug || !projectId) {
throw new Error("workspace slug or project id not provided");
}
const currentPageIds = this.getCurrentProjectPageIds(pageType);
runInAction(() => {
this.loader = currentPageIds && currentPageIds.length > 0 ? `mutation-loader` : `init-loader`;
this.loader = this.isAnyPageAvailable ? `mutation-loader` : `init-loader`;
this.error = undefined;
});
@@ -187,13 +184,15 @@ export class ProjectPageStore implements IProjectPageStore {
* @description fetch the details of a page
* @param {string} pageId
*/
getPageById = async (workspaceSlug: string, projectId: string, pageId: string) => {
fetchPageById = async (workspaceSlug: string, projectId: string, pageId: string) => {
try {
if (!workspaceSlug || !projectId || !pageId) return undefined;
if (!workspaceSlug || !projectId || !pageId) {
throw new Error("workspace slug, project id or page id not provided");
}
const currentPageId = this.pageById(pageId);
const currentPage = this.pageById(pageId);
runInAction(() => {
this.loader = currentPageId ? `mutation-loader` : `init-loader`;
this.loader = currentPage ? `mutation-loader` : `init-loader`;
this.error = undefined;
});
+1 -1
View File
@@ -14,7 +14,7 @@ export const filterPagesByPageType = (pageType: TPageNavigationTabs, pages: TPag
pages.filter((page) => {
if (pageType === "public") return page.access === 0 && !page.archived_at;
if (pageType === "private") return page.access === 1 && !page.archived_at;
if (pageType === "archived") return page.archived_at;
if (pageType === "trash") return page.archived_at;
return true;
});
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB