mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
[WEB-1135] chore: store page full width information in local storage (#4327)
* chore: store page full width information in local storage * chore: update page types
This commit is contained in:
parent
73fd6e641c
commit
eb0877a3c8
5
packages/types/src/pages.d.ts
vendored
5
packages/types/src/pages.d.ts
vendored
@ -16,14 +16,9 @@ export type TPage = {
|
||||
project: string | undefined;
|
||||
updated_at: Date | undefined;
|
||||
updated_by: string | undefined;
|
||||
view_props: TPageViewProps | undefined;
|
||||
workspace: string | undefined;
|
||||
};
|
||||
|
||||
export type TPageViewProps = {
|
||||
full_width?: boolean;
|
||||
};
|
||||
|
||||
// page filters
|
||||
export type TPageNavigationTabs = "public" | "private" | "archived";
|
||||
|
||||
|
@ -18,6 +18,7 @@ import { PageContentBrowser, PageEditorTitle } from "@/components/pages";
|
||||
import { cn } from "@/helpers/common.helper";
|
||||
// hooks
|
||||
import { useMember, useMention, useUser, useWorkspace } from "@/hooks/store";
|
||||
import { usePageFilters } from "@/hooks/use-page-filters";
|
||||
import useReloadConfirmations from "@/hooks/use-reload-confirmation";
|
||||
// services
|
||||
import { FileService } from "@/services/file.service";
|
||||
@ -68,7 +69,6 @@ export const PageEditorBody: React.FC<Props> = observer((props) => {
|
||||
const workspaceId = workspaceSlug ? getWorkspaceBySlug(workspaceSlug.toString())?.id ?? "" : "";
|
||||
const pageTitle = pageStore?.name ?? "";
|
||||
const pageDescription = pageStore?.description_html ?? "<p></p>";
|
||||
const isFullWidth = !!pageStore?.view_props?.full_width;
|
||||
const { description_html, isContentEditable, updateTitle, isSubmitting, setIsSubmitting } = pageStore;
|
||||
const projectMemberIds = projectId ? getProjectMemberIds(projectId.toString()) : [];
|
||||
const projectMemberDetails = projectMemberIds?.map((id) => getUserDetails(id) as IUserLite);
|
||||
@ -79,6 +79,8 @@ export const PageEditorBody: React.FC<Props> = observer((props) => {
|
||||
members: projectMemberDetails,
|
||||
user: currentUser ?? undefined,
|
||||
});
|
||||
// page filters
|
||||
const { isFullWidth } = usePageFilters();
|
||||
|
||||
const { setShowAlert } = useReloadConfirmations(isSubmitting === "submitting");
|
||||
|
||||
|
@ -2,6 +2,8 @@ import { observer } from "mobx-react";
|
||||
import { EditorReadOnlyRefApi, EditorRefApi, IMarking } from "@plane/document-editor";
|
||||
// components
|
||||
import { PageExtraOptions, PageSummaryPopover, PageToolbar } from "@/components/pages";
|
||||
// hooks
|
||||
import { usePageFilters } from "@/hooks/use-page-filters";
|
||||
// store
|
||||
import { IPageStore } from "@/store/pages/page.store";
|
||||
|
||||
@ -34,8 +36,9 @@ export const PageEditorMobileHeaderRoot: React.FC<Props> = observer((props) => {
|
||||
setSidePeekVisible,
|
||||
} = props;
|
||||
// derived values
|
||||
const { isContentEditable, view_props } = pageStore;
|
||||
const isFullWidth = !!view_props?.full_width;
|
||||
const { isContentEditable } = pageStore;
|
||||
// page filters
|
||||
const { isFullWidth } = usePageFilters();
|
||||
|
||||
if (!editorRef.current && !readOnlyEditorRef.current) return null;
|
||||
|
||||
|
@ -4,13 +4,11 @@ import { ArchiveRestoreIcon, Clipboard, Copy, Link, Lock, LockOpen } from "lucid
|
||||
import { EditorReadOnlyRefApi, EditorRefApi } from "@plane/document-editor";
|
||||
// ui
|
||||
import { ArchiveIcon, CustomMenu, TOAST_TYPE, ToggleSwitch, setToast } from "@plane/ui";
|
||||
// constants
|
||||
import { EUserProjectRoles } from "@/constants/project";
|
||||
// helpers
|
||||
import { cn } from "@/helpers/common.helper";
|
||||
import { copyTextToClipboard, copyUrlToClipboard } from "@/helpers/string.helper";
|
||||
// hooks
|
||||
import { useApplication, useUser } from "@/hooks/store";
|
||||
import { useApplication } from "@/hooks/store";
|
||||
import { usePageFilters } from "@/hooks/use-page-filters";
|
||||
// store
|
||||
import { IPageStore } from "@/store/pages/page.store";
|
||||
|
||||
@ -34,18 +32,13 @@ export const PageOptionsDropdown: React.FC<Props> = observer((props) => {
|
||||
canCurrentUserDuplicatePage,
|
||||
canCurrentUserLockPage,
|
||||
restore,
|
||||
view_props,
|
||||
updateViewProps,
|
||||
} = pageStore;
|
||||
// store hooks
|
||||
const {
|
||||
router: { workspaceSlug, projectId },
|
||||
} = useApplication();
|
||||
const {
|
||||
membership: { currentProjectRole },
|
||||
} = useUser();
|
||||
// auth
|
||||
const isEditingAllowed = !!currentProjectRole && currentProjectRole >= EUserProjectRoles.MEMBER;
|
||||
// page filters
|
||||
const { isFullWidth, handleFullWidth } = usePageFilters();
|
||||
|
||||
const handleArchivePage = async () =>
|
||||
await archive().catch(() =>
|
||||
@ -149,22 +142,10 @@ export const PageOptionsDropdown: React.FC<Props> = observer((props) => {
|
||||
<CustomMenu maxHeight="md" placement="bottom-start" verticalEllipsis closeOnSelect>
|
||||
<CustomMenu.MenuItem
|
||||
className="hidden md:flex w-full items-center justify-between gap-2"
|
||||
onClick={() =>
|
||||
updateViewProps({
|
||||
full_width: !view_props?.full_width,
|
||||
})
|
||||
}
|
||||
disabled={!isEditingAllowed}
|
||||
onClick={() => handleFullWidth(!isFullWidth)}
|
||||
>
|
||||
Full width
|
||||
<ToggleSwitch
|
||||
value={!!view_props?.full_width}
|
||||
onChange={() => {}}
|
||||
className={cn({
|
||||
"opacity-40": !isEditingAllowed,
|
||||
})}
|
||||
disabled={!isEditingAllowed}
|
||||
/>
|
||||
<ToggleSwitch value={isFullWidth} onChange={() => {}} />
|
||||
</CustomMenu.MenuItem>
|
||||
{MENU_ITEMS.map((item) => {
|
||||
if (!item.shouldRender) return null;
|
||||
|
@ -4,6 +4,8 @@ import { EditorReadOnlyRefApi, EditorRefApi, IMarking } from "@plane/document-ed
|
||||
import { PageEditorMobileHeaderRoot, PageExtraOptions, PageSummaryPopover, PageToolbar } from "@/components/pages";
|
||||
// helpers
|
||||
import { cn } from "@/helpers/common.helper";
|
||||
// hooks
|
||||
import { usePageFilters } from "@/hooks/use-page-filters";
|
||||
// store
|
||||
import { IPageStore } from "@/store/pages/page.store";
|
||||
|
||||
@ -36,8 +38,9 @@ export const PageEditorHeaderRoot: React.FC<Props> = observer((props) => {
|
||||
setSidePeekVisible,
|
||||
} = props;
|
||||
// derived values
|
||||
const { isContentEditable, view_props } = pageStore;
|
||||
const isFullWidth = !!view_props?.full_width;
|
||||
const { isContentEditable } = pageStore;
|
||||
// page filters
|
||||
const { isFullWidth } = usePageFilters();
|
||||
|
||||
if (!editorRef.current && !readOnlyEditorRef.current) return null;
|
||||
|
||||
|
12
web/hooks/use-page-filters.ts
Normal file
12
web/hooks/use-page-filters.ts
Normal file
@ -0,0 +1,12 @@
|
||||
// hooks
|
||||
import useLocalStorage from "@/hooks/use-local-storage";
|
||||
|
||||
export const usePageFilters = () => {
|
||||
const { storedValue: isFullWidth, setValue: setFullWidth } = useLocalStorage<boolean>("page_full_width", true);
|
||||
const handleFullWidth = (value: boolean) => setFullWidth(value);
|
||||
|
||||
return {
|
||||
isFullWidth: !!isFullWidth,
|
||||
handleFullWidth,
|
||||
};
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
import set from "lodash/set";
|
||||
import { action, computed, makeObservable, observable, reaction, runInAction } from "mobx";
|
||||
// types
|
||||
import { TPage, TPageViewProps } from "@plane/types";
|
||||
import { TPage } from "@plane/types";
|
||||
// constants
|
||||
import { EPageAccess } from "@/constants/page";
|
||||
import { EUserProjectRoles } from "@/constants/project";
|
||||
@ -33,7 +33,6 @@ export interface IPageStore extends TPage {
|
||||
cleanup: () => void;
|
||||
// actions
|
||||
update: (pageData: Partial<TPage>) => Promise<TPage | undefined>;
|
||||
updateViewProps: (viewProps: Partial<TPageViewProps>) => void;
|
||||
makePublic: () => Promise<void>;
|
||||
makePrivate: () => Promise<void>;
|
||||
lock: () => Promise<void>;
|
||||
@ -65,7 +64,6 @@ export class PageStore implements IPageStore {
|
||||
updated_by: string | undefined;
|
||||
created_at: Date | undefined;
|
||||
updated_at: Date | undefined;
|
||||
view_props: TPageViewProps | undefined;
|
||||
// helpers
|
||||
oldName: string = "";
|
||||
// reactions
|
||||
@ -93,7 +91,6 @@ export class PageStore implements IPageStore {
|
||||
this.updated_by = page?.updated_by || undefined;
|
||||
this.created_at = page?.created_at || undefined;
|
||||
this.updated_at = page?.updated_at || undefined;
|
||||
this.view_props = page?.view_props || undefined;
|
||||
this.oldName = page?.name || "";
|
||||
|
||||
makeObservable(this, {
|
||||
@ -117,7 +114,6 @@ export class PageStore implements IPageStore {
|
||||
updated_by: observable.ref,
|
||||
created_at: observable.ref,
|
||||
updated_at: observable.ref,
|
||||
view_props: observable,
|
||||
// helpers
|
||||
oldName: observable,
|
||||
// computed
|
||||
@ -137,7 +133,6 @@ export class PageStore implements IPageStore {
|
||||
cleanup: action,
|
||||
// actions
|
||||
update: action,
|
||||
updateViewProps: action,
|
||||
makePublic: action,
|
||||
makePrivate: action,
|
||||
lock: action,
|
||||
@ -216,7 +211,6 @@ export class PageStore implements IPageStore {
|
||||
updated_by: this.updated_by,
|
||||
created_at: this.created_at,
|
||||
updated_at: this.updated_at,
|
||||
view_props: this.view_props,
|
||||
};
|
||||
}
|
||||
|
||||
@ -338,38 +332,6 @@ export class PageStore implements IPageStore {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @description update the page view props
|
||||
* @param {Partial<TPageViewProps>} updatedProps
|
||||
*/
|
||||
updateViewProps = async (updatedProps: Partial<TPageViewProps>) => {
|
||||
const { workspaceSlug, projectId } = this.store.app.router;
|
||||
if (!workspaceSlug || !projectId || !this.id) return undefined;
|
||||
|
||||
const currentViewProps = { ...this.view_props };
|
||||
|
||||
runInAction(() => {
|
||||
Object.keys(updatedProps).forEach((key) => {
|
||||
const currentPageKey = key as keyof TPageViewProps;
|
||||
if (this.view_props) set(this.view_props, key, updatedProps[currentPageKey]);
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
await this.pageService.update(workspaceSlug, projectId, this.id, {
|
||||
view_props: {
|
||||
...this.view_props,
|
||||
...updatedProps,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
runInAction(() => {
|
||||
this.view_props = currentViewProps;
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @description make the page public
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user