plane/web/store/page.store.ts
Prateek Shourya 1539340113
chore: date and time standardization all across the platform. (#3283)
* chore: date and time standardization all across the platform.

* chore: update `renderFormattedTime` function.
* remove unwanted code.

* fix: build errors

* chore: update `renderFormattedTime` function params.
2024-01-02 14:45:51 +05:30

366 lines
11 KiB
TypeScript

import { observable, action, computed, makeObservable, runInAction } from "mobx";
import isYesterday from "date-fns/isYesterday";
import isToday from "date-fns/isToday";
import isThisWeek from "date-fns/isThisWeek";
// services
import { ProjectService } from "services/project";
import { PageService } from "services/page.service";
// helpers
import { renderFormattedPayloadDate } from "helpers/date-time.helper";
// types
import { RootStore } from "./root";
import { IPage, IRecentPages } from "types";
export interface IPageStore {
loader: boolean;
error: any | null;
pages: {
[project_id: string]: IPage[];
};
archivedPages: {
[project_id: string]: IPage[];
};
//computed
projectPages: IPage[] | undefined;
recentProjectPages: IRecentPages | undefined;
favoriteProjectPages: IPage[] | undefined;
privateProjectPages: IPage[] | undefined;
sharedProjectPages: IPage[] | undefined;
archivedProjectPages: IPage[] | undefined;
// actions
fetchPages: (workspaceSlug: string, projectId: string) => Promise<IPage[]>;
createPage: (workspaceSlug: string, projectId: string, data: Partial<IPage>) => Promise<IPage>;
updatePage: (workspaceSlug: string, projectId: string, pageId: string, data: Partial<IPage>) => Promise<IPage>;
deletePage: (workspaceSlug: string, projectId: string, pageId: string) => Promise<void>;
addToFavorites: (workspaceSlug: string, projectId: string, pageId: string) => Promise<void>;
removeFromFavorites: (workspaceSlug: string, projectId: string, pageId: string) => Promise<void>;
makePublic: (workspaceSlug: string, projectId: string, pageId: string) => Promise<IPage>;
makePrivate: (workspaceSlug: string, projectId: string, pageId: string) => Promise<IPage>;
fetchArchivedPages: (workspaceSlug: string, projectId: string) => Promise<IPage[]>;
archivePage: (workspaceSlug: string, projectId: string, pageId: string) => Promise<void>;
restorePage: (workspaceSlug: string, projectId: string, pageId: string) => Promise<void>;
}
export class PageStore implements IPageStore {
loader: boolean = false;
error: any | null = null;
pages: { [project_id: string]: IPage[] } = {};
archivedPages: { [project_id: string]: IPage[] } = {};
// root store
rootStore;
// service
projectService;
pageService;
constructor(_rootStore: RootStore) {
makeObservable(this, {
// observable
loader: observable,
error: observable,
pages: observable.ref,
archivedPages: observable.ref,
// computed
projectPages: computed,
recentProjectPages: computed,
favoriteProjectPages: computed,
privateProjectPages: computed,
sharedProjectPages: computed,
archivedProjectPages: computed,
// action
fetchPages: action,
createPage: action,
updatePage: action,
deletePage: action,
addToFavorites: action,
removeFromFavorites: action,
makePublic: action,
makePrivate: action,
archivePage: action,
restorePage: action,
fetchArchivedPages: action,
});
this.rootStore = _rootStore;
this.projectService = new ProjectService();
this.pageService = new PageService();
}
get projectPages() {
const projectId = this.rootStore.project.projectId;
if (!projectId || !this.pages[projectId]) return undefined;
return this.pages?.[projectId] || [];
}
get recentProjectPages() {
const projectId = this.rootStore.project.projectId;
if (!projectId) return undefined;
if (!this.pages[projectId]) return undefined;
const data: IRecentPages = { today: [], yesterday: [], this_week: [], older: [] };
data.today = this.pages[projectId]?.filter((p) => isToday(new Date(p.created_at))) || [];
data.yesterday = this.pages[projectId]?.filter((p) => isYesterday(new Date(p.created_at))) || [];
data.this_week =
this.pages[projectId]?.filter(
(p) =>
isThisWeek(new Date(p.created_at)) && !isToday(new Date(p.created_at)) && !isYesterday(new Date(p.created_at))
) || [];
data.older =
this.pages[projectId]?.filter(
(p) => !isThisWeek(new Date(p.created_at)) && !isYesterday(new Date(p.created_at))
) || [];
return data;
}
get favoriteProjectPages() {
const projectId = this.rootStore.project.projectId;
if (!projectId || !this.pages[projectId]) return undefined;
return this.pages[projectId]?.filter((p) => p.is_favorite);
}
get privateProjectPages() {
const projectId = this.rootStore.project.projectId;
if (!projectId || !this.pages[projectId]) return undefined;
return this.pages[projectId]?.filter((p) => p.access === 1);
}
get sharedProjectPages() {
const projectId = this.rootStore.project.projectId;
if (!projectId || !this.pages[projectId]) return undefined;
return this.pages[projectId]?.filter((p) => p.access === 0);
}
get archivedProjectPages() {
const projectId = this.rootStore.project.projectId;
if (!projectId || !this.archivedPages[projectId]) return undefined;
return this.archivedPages[projectId];
}
addToFavorites = async (workspaceSlug: string, projectId: string, pageId: string) => {
try {
runInAction(() => {
this.pages = {
...this.pages,
[projectId]: this.pages[projectId].map((page) => {
if (page.id === pageId) {
return { ...page, is_favorite: true };
}
return page;
}),
};
});
await this.pageService.addPageToFavorites(workspaceSlug, projectId, pageId);
} catch (error) {
throw error;
}
};
removeFromFavorites = async (workspaceSlug: string, projectId: string, pageId: string) => {
try {
runInAction(() => {
this.pages = {
...this.pages,
[projectId]: this.pages[projectId].map((page) => {
if (page.id === pageId) {
return { ...page, is_favorite: false };
}
return page;
}),
};
});
await this.pageService.removePageFromFavorites(workspaceSlug, projectId, pageId);
} catch (error) {
throw error;
}
};
fetchPages = async (workspaceSlug: string, projectId: string) => {
try {
this.loader = true;
this.error = null;
const response = await this.pageService.getPagesWithParams(workspaceSlug, projectId, "all");
runInAction(() => {
this.pages = {
...this.pages,
[projectId]: response,
};
this.loader = false;
this.error = null;
});
return response;
} catch (error) {
console.error("Failed to fetch project pages in project store", error);
this.loader = false;
this.error = error;
throw error;
}
};
createPage = async (workspaceSlug: string, projectId: string, data: Partial<IPage>) => {
try {
const response = await this.pageService.createPage(workspaceSlug, projectId, data);
runInAction(() => {
this.pages = {
...this.pages,
[projectId]: [...this.pages[projectId], response],
};
});
return response;
} catch (error) {
throw error;
}
};
updatePage = async (workspaceSlug: string, projectId: string, pageId: string, data: Partial<IPage>) => {
try {
runInAction(() => {
this.pages = {
...this.pages,
[projectId]: this.pages[projectId]?.map((page) => {
if (page.id === pageId) {
return { ...page, ...data };
}
return page;
}),
};
});
const response = await this.pageService.patchPage(workspaceSlug, projectId, pageId, data);
return response;
} catch (error) {
throw error;
}
};
deletePage = async (workspaceSlug: string, projectId: string, pageId: string) => {
try {
runInAction(() => {
this.archivedPages = {
...this.archivedPages,
[projectId]: this.archivedPages[projectId]?.filter((page) => page.id !== pageId),
};
});
const response = await this.pageService.deletePage(workspaceSlug, projectId, pageId);
return response;
} catch (error) {
throw error;
}
};
makePublic = async (workspaceSlug: string, projectId: string, pageId: string) => {
try {
runInAction(() => {
this.pages = {
...this.pages,
[projectId]: this.pages[projectId]?.map((page) => ({
...page,
access: page.id === pageId ? 0 : page.access,
})),
};
});
const response = await this.pageService.patchPage(workspaceSlug, projectId, pageId, { access: 0 });
return response;
} catch (error) {
throw error;
}
};
makePrivate = async (workspaceSlug: string, projectId: string, pageId: string) => {
try {
runInAction(() => {
this.pages = {
...this.pages,
[projectId]: this.pages[projectId]?.map((page) => ({
...page,
access: page.id === pageId ? 1 : page.access,
})),
};
});
const response = await this.pageService.patchPage(workspaceSlug, projectId, pageId, { access: 1 });
return response;
} catch (error) {
throw error;
}
};
fetchArchivedPages = async (workspaceSlug: string, projectId: string) => {
try {
const response = await this.pageService.getArchivedPages(workspaceSlug, projectId);
runInAction(() => {
this.archivedPages = {
...this.archivedPages,
[projectId]: response,
};
});
return response;
} catch (error) {
throw error;
}
};
archivePage = async (workspaceSlug: string, projectId: string, pageId: string) => {
try {
const archivedPage = this.pages[projectId]?.find((page) => page.id === pageId);
if (archivedPage) {
runInAction(() => {
this.pages = {
...this.pages,
[projectId]: [...this.pages[projectId]?.filter((page) => page.id != pageId)],
};
this.archivedPages = {
...this.archivedPages,
[projectId]: [
...this.archivedPages[projectId],
{ ...archivedPage, archived_at: renderFormattedPayloadDate(new Date()) },
],
};
});
}
await this.pageService.archivePage(workspaceSlug, projectId, pageId);
} catch (error) {
throw error;
}
};
restorePage = async (workspaceSlug: string, projectId: string, pageId: string) => {
try {
const restoredPage = this.archivedPages[projectId]?.find((page) => page.id === pageId);
if (restoredPage) {
runInAction(() => {
this.pages = {
...this.pages,
[projectId]: [...this.pages[projectId], { ...restoredPage, archived_at: null }],
};
this.archivedPages = {
...this.archivedPages,
[projectId]: [...this.archivedPages[projectId]?.filter((page) => page.id != pageId)],
};
});
}
await this.pageService.restorePage(workspaceSlug, projectId, pageId);
} catch (error) {
throw error;
}
};
}