From 671bf7e1fee40c45eda4d60bda0fb6728e506458 Mon Sep 17 00:00:00 2001 From: gurusainath Date: Wed, 16 Aug 2023 13:29:50 +0530 Subject: [PATCH 1/3] chore: updating the theme using mobx from command k --- .../change-interface-theme.tsx | 36 +++++++------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/apps/app/components/command-palette/change-interface-theme.tsx b/apps/app/components/command-palette/change-interface-theme.tsx index 34ebf35625e..87d1289aec0 100644 --- a/apps/app/components/command-palette/change-interface-theme.tsx +++ b/apps/app/components/command-palette/change-interface-theme.tsx @@ -9,12 +9,18 @@ import userService from "services/user.service"; import useUser from "hooks/use-user"; // helper import { unsetCustomCssVariables } from "helpers/theme.helper"; +// mobx react lite +import { observer } from "mobx-react-lite"; +// mobx store +import { useMobxStore } from "lib/mobx/store-provider"; type Props = { setIsPaletteOpen: Dispatch>; }; -export const ChangeInterfaceTheme: React.FC = ({ setIsPaletteOpen }) => { +export const ChangeInterfaceTheme: React.FC = observer(({ setIsPaletteOpen }) => { + const store: any = useMobxStore(); + const [mounted, setMounted] = useState(false); const { setTheme } = useTheme(); @@ -23,29 +29,11 @@ export const ChangeInterfaceTheme: React.FC = ({ setIsPaletteOpen }) => { const updateUserTheme = (newTheme: string) => { if (!user) return; - - unsetCustomCssVariables(); - setTheme(newTheme); - - mutateUser((prevData: any) => { - if (!prevData) return prevData; - - return { - ...prevData, - theme: { - ...prevData?.theme, - theme: newTheme, - }, - }; - }, false); - - userService.updateUser({ - theme: { - ...user.theme, - theme: newTheme, - }, - }); + return store.user + .updateCurrentUserSettings({ theme: { ...user.theme, theme: newTheme } }) + .then((response: any) => response) + .catch((error: any) => error); }; // useEffect only runs on the client, so now we can safely show the UI @@ -74,4 +62,4 @@ export const ChangeInterfaceTheme: React.FC = ({ setIsPaletteOpen }) => { ))} ); -}; +}); From 6c32d8b24fe9f5a9b3b44f3962fd150390b83f9f Mon Sep 17 00:00:00 2001 From: gurusainath Date: Wed, 16 Aug 2023 14:44:42 +0530 Subject: [PATCH 2/3] feat: Showing the project published status in the app header --- apps/app/layouts/app-layout/app-header.tsx | 58 ++++++++++++++-------- apps/app/types/projects.d.ts | 1 + 2 files changed, 39 insertions(+), 20 deletions(-) diff --git a/apps/app/layouts/app-layout/app-header.tsx b/apps/app/layouts/app-layout/app-header.tsx index f63d65650ef..3c9bf2c9b1b 100644 --- a/apps/app/layouts/app-layout/app-header.tsx +++ b/apps/app/layouts/app-layout/app-header.tsx @@ -1,5 +1,7 @@ // icons import { Bars3Icon } from "@heroicons/react/24/outline"; +// hooks +import useProjectDetails from "hooks/use-project-details"; type Props = { breadcrumbs?: JSX.Element; @@ -9,27 +11,43 @@ type Props = { noHeader: boolean; }; -const Header: React.FC = ({ breadcrumbs, left, right, setToggleSidebar, noHeader }) => ( -
-
-
- +const Header: React.FC = ({ breadcrumbs, left, right, setToggleSidebar, noHeader }) => { + const { projectDetails } = useProjectDetails(); + + console.log("projectDetails", projectDetails); + + return ( +
+
+
+ +
+
{breadcrumbs}
+ + {projectDetails && projectDetails?.is_deployed && ( +
+
+ radio_button_checked +
+
Published
+
+ )} + +
{left}
- {breadcrumbs} -
{left}
+
{right}
-
{right}
-
-); + ); +}; export default Header; diff --git a/apps/app/types/projects.d.ts b/apps/app/types/projects.d.ts index d620a24b7ae..a3d8b997a57 100644 --- a/apps/app/types/projects.d.ts +++ b/apps/app/types/projects.d.ts @@ -57,6 +57,7 @@ export interface IProject { updated_by: string; workspace: IWorkspace | string; workspace_detail: IWorkspaceLite; + is_deployed: boolean; } export interface IProjectLite { From d1532dd91732a968e9aba6df9c28a039410b1448 Mon Sep 17 00:00:00 2001 From: gurusainath Date: Wed, 16 Aug 2023 18:24:26 +0530 Subject: [PATCH 3/3] dev: updated validation and redirection the project publish modal and added redirection on the app header --- .../project/publish-project/modal.tsx | 82 +++++++++++++------ apps/app/layouts/app-layout/app-header.tsx | 37 +++++++-- apps/app/store/project-publish.tsx | 14 ++-- 3 files changed, 91 insertions(+), 42 deletions(-) diff --git a/apps/app/components/project/publish-project/modal.tsx b/apps/app/components/project/publish-project/modal.tsx index d9171949726..5f9d9ae2cbd 100644 --- a/apps/app/components/project/publish-project/modal.tsx +++ b/apps/app/components/project/publish-project/modal.tsx @@ -14,6 +14,9 @@ import { observer } from "mobx-react-lite"; import { useMobxStore } from "lib/mobx/store-provider"; import { RootStore } from "store/root"; import { IProjectPublishSettingsViews } from "store/project-publish"; +// hooks +import useToast from "hooks/use-toast"; +import useProjectDetails from "hooks/use-project-details"; type Props = { // user: ICurrentUserResponse | undefined; @@ -25,7 +28,7 @@ const defaultValues: Partial = { reactions: false, votes: false, inbox: null, - views: [], + views: ["list", "kanban"], }; const viewOptions = [ @@ -40,6 +43,17 @@ export const PublishProjectModal: React.FC = observer(() => { const store: RootStore = useMobxStore(); const { projectPublish } = store; + const { projectDetails, mutateProjectDetails } = useProjectDetails(); + + const { setToastAlert } = useToast(); + const handleToastAlert = (title: string, type: string, message: string) => { + setToastAlert({ + title: title || "Title", + type: "error" || "warning", + message: message || "Message", + }); + }; + const { NEXT_PUBLIC_DEPLOY_URL } = process.env; const plane_deploy_url = NEXT_PUBLIC_DEPLOY_URL ? NEXT_PUBLIC_DEPLOY_URL @@ -111,32 +125,41 @@ export const PublishProjectModal: React.FC = observer(() => { }, [workspaceSlug, projectPublish, projectPublish.projectPublishModal]); const onSettingsPublish = async (formData: any) => { - const payload = { - comments: formData.comments || false, - reactions: formData.reactions || false, - votes: formData.votes || false, - inbox: formData.inbox || null, - views: { - list: formData.views.includes("list") || false, - kanban: formData.views.includes("kanban") || false, - calendar: formData.views.includes("calendar") || false, - gantt: formData.views.includes("gantt") || false, - spreadsheet: formData.views.includes("spreadsheet") || false, - }, - }; + if (formData.views && formData.views.length > 0) { + const payload = { + comments: formData.comments || false, + reactions: formData.reactions || false, + votes: formData.votes || false, + inbox: formData.inbox || null, + views: { + list: formData.views.includes("list") || false, + kanban: formData.views.includes("kanban") || false, + calendar: formData.views.includes("calendar") || false, + gantt: formData.views.includes("gantt") || false, + spreadsheet: formData.views.includes("spreadsheet") || false, + }, + }; - return projectPublish - .createProjectSettingsAsync( - workspaceSlug as string, - projectPublish.project_id as string, - payload, - null - ) - .then((response) => response) - .catch((error) => { - console.error("error", error); - return error; - }); + const _workspaceSlug = workspaceSlug; + const _projectId = projectPublish.project_id; + + return projectPublish + .createProjectSettingsAsync(_workspaceSlug as string, _projectId as string, payload, null) + .then((response) => { + mutateProjectDetails(); + handleClose(); + console.log("_projectId", _projectId); + if (_projectId) + window.open(`${plane_deploy_url}/${_workspaceSlug}/${_projectId}`, "_blank"); + return response; + }) + .catch((error) => { + console.error("error", error); + return error; + }); + } else { + handleToastAlert("Missing fields", "warning", "Please select at least one view to publish"); + } }; const onSettingsUpdate = async (key: string, value: any) => { @@ -171,7 +194,10 @@ export const PublishProjectModal: React.FC = observer(() => { payload, null ) - .then((response) => response) + .then((response) => { + mutateProjectDetails(); + return response; + }) .catch((error) => { console.log("error", error); return error; @@ -187,7 +213,9 @@ export const PublishProjectModal: React.FC = observer(() => { null ) .then((response) => { + mutateProjectDetails(); reset({ ...defaultValues }); + handleClose(); return response; }) .catch((error) => { diff --git a/apps/app/layouts/app-layout/app-header.tsx b/apps/app/layouts/app-layout/app-header.tsx index 3c9bf2c9b1b..f2fbdc78c3b 100644 --- a/apps/app/layouts/app-layout/app-header.tsx +++ b/apps/app/layouts/app-layout/app-header.tsx @@ -1,5 +1,10 @@ +// next imports +import { useRouter } from "next/router"; +import Link from "next/link"; // icons import { Bars3Icon } from "@heroicons/react/24/outline"; +// ui components +import { Tooltip } from "components/ui"; // hooks import useProjectDetails from "hooks/use-project-details"; @@ -11,10 +16,14 @@ type Props = { noHeader: boolean; }; +const { NEXT_PUBLIC_DEPLOY_URL } = process.env; +const plane_deploy_url = NEXT_PUBLIC_DEPLOY_URL ? NEXT_PUBLIC_DEPLOY_URL : "http://localhost:3001"; + const Header: React.FC = ({ breadcrumbs, left, right, setToggleSidebar, noHeader }) => { const { projectDetails } = useProjectDetails(); - console.log("projectDetails", projectDetails); + const router = useRouter(); + const { workspaceSlug, projectId } = router.query; return (
= ({ breadcrumbs, left, right, setToggleSidebar, n
{breadcrumbs}
{projectDetails && projectDetails?.is_deployed && ( -
-
- radio_button_checked -
-
Published
-
+ + + +
+
+ + radio_button_checked + +
+
Public
+
+ open_in_new +
+
+
+
+ )}
{left}
diff --git a/apps/app/store/project-publish.tsx b/apps/app/store/project-publish.tsx index d1b4c58a7c3..1b27d5fff9c 100644 --- a/apps/app/store/project-publish.tsx +++ b/apps/app/store/project-publish.tsx @@ -259,15 +259,13 @@ class ProjectPublishStore implements IProjectPublishStore { user ); - if (response) { - runInAction(() => { - this.projectPublishSettings = "not-initialized"; - this.loader = false; - this.error = null; - }); + runInAction(() => { + this.projectPublishSettings = "not-initialized"; + this.loader = false; + this.error = null; + }); - return response; - } + return response; } catch (error) { this.loader = false; this.error = error;