diff --git a/apps/space/components/accounts/index.ts b/apps/space/components/accounts/index.ts
new file mode 100644
index 0000000000..093e8538c4
--- /dev/null
+++ b/apps/space/components/accounts/index.ts
@@ -0,0 +1,6 @@
+export * from "./email-code-form";
+export * from "./email-password-form";
+export * from "./email-reset-password-form";
+export * from "./github-login-button";
+export * from "./google-login";
+export * from "./onboarding-form";
diff --git a/apps/space/components/issues/board-views/list/block.tsx b/apps/space/components/issues/board-views/list/block.tsx
index fcb123c217..bbac97741c 100644
--- a/apps/space/components/issues/board-views/list/block.tsx
+++ b/apps/space/components/issues/board-views/list/block.tsx
@@ -1,6 +1,5 @@
-"use client";
-
-// mobx react lite
+import { FC } from "react";
+import { useRouter } from "next/router";
import { observer } from "mobx-react-lite";
// components
import { IssueBlockPriority } from "components/issues/board-views/block-priority";
@@ -11,10 +10,32 @@ import { IssueBlockDueDate } from "components/issues/board-views/block-due-date"
import { useMobxStore } from "lib/mobx/store-provider";
// interfaces
import { IIssue } from "types/issue";
+// store
import { RootStore } from "store/root";
-export const IssueListBlock = observer(({ issue }: { issue: IIssue }) => {
- const { issue: issueStore, project: projectStore, issueDetails: issueDetailStore }: RootStore = useMobxStore();
+export const IssueListBlock: FC<{ issue: IIssue }> = observer((props) => {
+ const { issue } = props;
+ // store
+ const { project: projectStore, issueDetails: issueDetailStore }: RootStore = useMobxStore();
+ // router
+ const router = useRouter();
+ const { workspace_slug, project_slug, board } = router.query;
+
+ const handleBlockClick = () => {
+ issueDetailStore.setPeekId(issue.id);
+ router.replace(
+ {
+ pathname: `/${workspace_slug?.toString()}/${project_slug}`,
+ query: {
+ board: board?.toString(),
+ peekId: issue.id,
+ },
+ },
+ undefined,
+ { shallow: true }
+ );
+ // router.push(`/${workspace_slug?.toString()}/${project_slug}?board=${board?.toString()}&peekId=${issue.id}`);
+ };
return (
@@ -25,12 +46,7 @@ export const IssueListBlock = observer(({ issue }: { issue: IIssue }) => {
{/* name */}
-
{
- issueDetailStore.setPeekId(issue.id);
- }}
- className="text-[0.825rem] font-medium text-sm truncate text-custom-text-100"
- >
+
{issue.name}
diff --git a/apps/space/components/issues/board-views/list/index.tsx b/apps/space/components/issues/board-views/list/index.tsx
index 268c27fc18..8d31199b03 100644
--- a/apps/space/components/issues/board-views/list/index.tsx
+++ b/apps/space/components/issues/board-views/list/index.tsx
@@ -1,6 +1,4 @@
-"use client";
-
-// mobx react lite
+import { useEffect } from "react";
import { observer } from "mobx-react-lite";
// components
import { IssueListHeader } from "components/issues/board-views/list/header";
@@ -9,11 +7,13 @@ import { IssueListBlock } from "components/issues/board-views/list/block";
import { IIssueState, IIssue } from "types/issue";
// mobx hook
import { useMobxStore } from "lib/mobx/store-provider";
+// store
import { RootStore } from "store/root";
+import { useRouter } from "next/router";
export const IssueListView = observer(() => {
const { issue: issueStore }: RootStore = useMobxStore();
- console.log("issueStore", issueStore.states);
+
return (
<>
{issueStore?.states &&
diff --git a/apps/space/components/issues/peek-overview/add-comment.tsx b/apps/space/components/issues/peek-overview/add-comment.tsx
index 618552aaf9..52c3b997f9 100644
--- a/apps/space/components/issues/peek-overview/add-comment.tsx
+++ b/apps/space/components/issues/peek-overview/add-comment.tsx
@@ -11,13 +11,7 @@ import { SecondaryButton } from "components/ui";
// types
import { Comment } from "types";
// components
-import Tiptap, { ITiptapRichTextEditor } from "components/tiptap";
-
-const TiptapEditor = React.forwardRef((props, ref) => (
-
-));
-
-TiptapEditor.displayName = "TiptapEditor";
+import { TipTapEditor } from "components/tiptap";
const defaultValues: Partial = {
comment_json: "",
@@ -25,12 +19,11 @@ const defaultValues: Partial = {
};
type Props = {
- issueId: string | null;
disabled?: boolean;
};
export const AddComment: React.FC = observer((props) => {
- const { issueId, disabled = false } = props;
+ const { disabled = false } = props;
const {
handleSubmit,
@@ -44,7 +37,9 @@ export const AddComment: React.FC = observer((props) => {
const router = useRouter();
const { workspace_slug, project_slug } = router.query as { workspace_slug: string; project_slug: string };
- const { issue: issueStore, user: userStore } = useMobxStore();
+ const { issue: issueStore, user: userStore, issueDetails: issueDetailStore } = useMobxStore();
+
+ const issueId = issueDetailStore.peekId;
const editorRef = useRef(null);
@@ -61,8 +56,8 @@ export const AddComment: React.FC = observer((props) => {
)
return;
- await issueStore
- .createIssueCommentAsync(workspace_slug, project_slug, issueId, formData)
+ await issueDetailStore
+ .addIssueComment(workspace_slug, project_slug, issueId, formData)
.then(() => {
reset(defaultValues);
editorRef.current?.clearEditor();
@@ -83,7 +78,7 @@ export const AddComment: React.FC = observer((props) => {
name="comment_html"
control={control}
render={({ field: { value, onChange } }) => (
- ((props, ref) => (
-
-));
-
-TiptapEditor.displayName = "TiptapEditor";
+import { TipTapEditor } from "components/tiptap";
type Props = {
workspaceSlug: string;
@@ -124,7 +118,7 @@ export const CommentCard: React.FC = observer((props) => {
className={`flex-col gap-2 ${isEditing ? "flex" : "hidden"}`}
>
- = observer((props) => {
-
= observer((props) => {
const router = useRouter();
- const { workspaceSlug } = router.query;
+ const { workspace_slug } = router.query;
const { issueDetails: issueDetailStore, user: userStore } = useMobxStore();
- const issueId = issueDetailStore?.peekId;
- const comments = issueDetailStore?.details[issueId ?? ""]?.comments ?? [];
+ const comments = issueDetailStore.details[issueDetailStore.peekId || ""]?.comments || [];
return (
Activity
- {workspaceSlug && (
+ {workspace_slug && (
{comments.map((comment: any) => (
-
+
))}
)}
diff --git a/apps/space/components/issues/peek-overview/issue-details.tsx b/apps/space/components/issues/peek-overview/issue-details.tsx
index bbe982a69c..ff725182d0 100644
--- a/apps/space/components/issues/peek-overview/issue-details.tsx
+++ b/apps/space/components/issues/peek-overview/issue-details.tsx
@@ -1,4 +1,3 @@
-// components
import { IssueReactions } from "components/issues/peek-overview";
// types
import { IIssue } from "types";
diff --git a/apps/space/components/issues/peek-overview/issue-emoji-reactions.tsx b/apps/space/components/issues/peek-overview/issue-emoji-reactions.tsx
index 2f51b59550..04bd9f63b5 100644
--- a/apps/space/components/issues/peek-overview/issue-emoji-reactions.tsx
+++ b/apps/space/components/issues/peek-overview/issue-emoji-reactions.tsx
@@ -9,22 +9,21 @@ import { groupReactions, renderEmoji } from "helpers/emoji.helper";
import { ReactionSelector } from "components/ui";
export const IssueEmojiReactions: React.FC = observer(() => {
+ // router
const router = useRouter();
-
const { workspace_slug, project_slug } = router.query as { workspace_slug: string; project_slug: string };
-
- const { user: userStore, issue: issueStore } = useMobxStore();
+ // store
+ const { user: userStore, issue: issueStore, issueDetails: issueDetailsStore } = useMobxStore();
const user = userStore?.currentUser;
- const issueId = issueStore.activePeekOverviewIssueId;
-
- const reactions = issueId ? issueStore.issue_detail[issueId]?.reactions || [] : [];
+ const issueId = issueDetailsStore.peekId;
+ const reactions = issueId ? issueDetailsStore.details[issueId]?.reactions || [] : [];
const groupedReactions = groupReactions(reactions, "reaction");
const handleReactionClick = (reactionHexa: string) => {
if (!workspace_slug || !project_slug || !issueId) return;
- const userReaction = reactions?.find((r) => r.created_by === user?.id && r.reaction === reactionHexa);
+ const userReaction = reactions?.find((r: any) => r.created_by === user?.id && r.reaction === reactionHexa);
if (userReaction)
issueStore.deleteIssueReactionAsync(workspace_slug, userReaction.project, userReaction.issue, reactionHexa);
@@ -34,12 +33,6 @@ export const IssueEmojiReactions: React.FC = observer(() => {
});
};
- useEffect(() => {
- if (user) return;
-
- userStore.getUserAsync();
- }, [user, userStore]);
-
return (
<>
{
}}
key={reaction}
className={`flex items-center gap-1 text-custom-text-100 text-sm h-full px-2 py-1 rounded-md border ${
- reactions?.some((r) => r.actor === user?.id && r.reaction === reaction)
+ reactions?.some((r: any) => r.actor === user?.id && r.reaction === reaction)
? "bg-custom-primary-100/10 border-custom-primary-100"
: "bg-custom-background-80 border-transparent"
}`}
@@ -71,7 +64,7 @@ export const IssueEmojiReactions: React.FC = observer(() => {
{renderEmoji(reaction)}
r.actor === user?.id && r.reaction === reaction)
+ reactions?.some((r: any) => r.actor === user?.id && r.reaction === reaction)
? "text-custom-primary-100"
: ""
}
diff --git a/apps/space/components/issues/peek-overview/issue-reaction.tsx b/apps/space/components/issues/peek-overview/issue-reaction.tsx
index 9dc1fac403..fc1b15e513 100644
--- a/apps/space/components/issues/peek-overview/issue-reaction.tsx
+++ b/apps/space/components/issues/peek-overview/issue-reaction.tsx
@@ -1,18 +1,25 @@
-"use client";
-
-// ui
import { IssueEmojiReactions, IssueVotes } from "components/issues/peek-overview";
+import { useMobxStore } from "lib/mobx/store-provider";
-export const IssueReactions: React.FC = () => (
-
-
-
+export const IssueReactions: React.FC = () => {
+ const { project: projectStore } = useMobxStore();
+ return (
+
+ {projectStore?.deploySettings?.votes && (
+ <>
+
+
+
+
+
+ >
+ )}
+
+ {projectStore?.deploySettings?.reactions && (
+
+
+
+ )}
-
-
-
-
-
-
-
-);
+ );
+};
diff --git a/apps/space/components/issues/peek-overview/layout.tsx b/apps/space/components/issues/peek-overview/layout.tsx
index ee763d1480..c50bd70663 100644
--- a/apps/space/components/issues/peek-overview/layout.tsx
+++ b/apps/space/components/issues/peek-overview/layout.tsx
@@ -1,4 +1,4 @@
-import React, { useEffect, useState } from "react";
+import React, { useEffect, useMemo } from "react";
import { useRouter } from "next/router";
import { Dialog, Transition } from "@headlessui/react";
import { observer } from "mobx-react-lite";
@@ -18,20 +18,19 @@ export const IssuePeekOverview: React.FC
= observer((props) => {
const { isOpen, onClose } = props;
// router
const router = useRouter();
- const { workspace_slug, project_slug } = router.query;
+ const { workspace_slug, project_slug, peekId } = router.query;
// store
- const { issueDetails: issueDetailStore } = useMobxStore();
+ const { issueDetails: issueDetailStore, issue: issueStore } = useMobxStore();
- const issueDetails = issueDetailStore.peekId ? issueDetailStore.details[issueDetailStore.peekId] : null;
- console.log("issueDetails", issueDetails);
+ const issueDetails = issueDetailStore.peekId && peekId ? issueDetailStore.details[peekId.toString()] : null;
useEffect(() => {
- if (workspace_slug && project_slug && issueDetailStore.peekId) {
+ if (workspace_slug && project_slug && peekId && issueStore.issues && issueStore.issues.length > 0) {
if (!issueDetails) {
- issueDetailStore.fetchIssueDetails(workspace_slug.toString(), project_slug.toString(), issueDetailStore.peekId);
+ issueDetailStore.fetchIssueDetails(workspace_slug.toString(), project_slug.toString(), peekId.toString());
}
}
- }, [workspace_slug, project_slug, issueDetailStore, issueDetails]);
+ }, [workspace_slug, project_slug, issueDetailStore, issueDetails, peekId, issueStore.issues]);
const handleClose = () => {
onClose();
diff --git a/apps/space/components/issues/peek-overview/side-peek-view.tsx b/apps/space/components/issues/peek-overview/side-peek-view.tsx
index 094565c933..967c2ae692 100644
--- a/apps/space/components/issues/peek-overview/side-peek-view.tsx
+++ b/apps/space/components/issues/peek-overview/side-peek-view.tsx
@@ -11,6 +11,7 @@ import {
} from "components/issues/peek-overview";
// types
import { IIssue } from "types/issue";
+import { RootStore } from "store/root";
type Props = {
handleClose: () => void;
@@ -20,6 +21,8 @@ type Props = {
export const SidePeekView: React.FC = observer((props) => {
const { handleClose, issueDetails } = props;
+ const { project: projectStore } = useMobxStore();
+
return (
@@ -38,9 +41,11 @@ export const SidePeekView: React.FC
= observer((props) => {
{/* divider */}
{/* issue activity/comments */}
-
+ {projectStore?.deploySettings?.comments && (
+
+ )}
)}
diff --git a/apps/space/components/tiptap/index.tsx b/apps/space/components/tiptap/index.tsx
index 418449c089..f0315cad4a 100644
--- a/apps/space/components/tiptap/index.tsx
+++ b/apps/space/components/tiptap/index.tsx
@@ -3,10 +3,10 @@ import { useDebouncedCallback } from "use-debounce";
import { EditorBubbleMenu } from "./bubble-menu";
import { TiptapExtensions } from "./extensions";
import { TiptapEditorProps } from "./props";
-import { useImperativeHandle, useRef } from "react";
+import { useImperativeHandle, useRef, forwardRef } from "react";
import { ImageResizer } from "./extensions/image-resize";
-export interface ITiptapRichTextEditor {
+export interface ITipTapRichTextEditor {
value: string;
noBorder?: boolean;
borderOnFocus?: boolean;
@@ -21,7 +21,7 @@ export interface ITiptapRichTextEditor {
debouncedUpdatesEnabled?: boolean;
}
-const Tiptap = (props: ITiptapRichTextEditor) => {
+const Tiptap = (props: ITipTapRichTextEditor) => {
const {
onChange,
debouncedUpdatesEnabled,
@@ -73,9 +73,10 @@ const Tiptap = (props: ITiptapRichTextEditor) => {
}, 500);
}, 1000);
- const editorClassNames = `relative w-full max-w-screen-lg sm:rounded-lg mt-2 p-3 relative focus:outline-none rounded-md
- ${noBorder ? "" : "border border-custom-border-200"} ${borderOnFocus ? "focus:border border-custom-border-300" : "focus:border-0"
- } ${customClassName}`;
+ const editorClassNames = `relative w-full max-w-full sm:rounded-lg mt-2 p-3 relative focus:outline-none rounded-md
+ ${noBorder ? "" : "border border-custom-border-200"} ${
+ borderOnFocus ? "focus:border border-custom-border-300" : "focus:border-0"
+ } ${customClassName}`;
if (!editor) return null;
editorRef.current = editor;
@@ -97,4 +98,10 @@ const Tiptap = (props: ITiptapRichTextEditor) => {
);
};
-export default Tiptap;
+const TipTapEditor = forwardRef((props, ref) => (
+
+));
+
+TipTapEditor.displayName = "TipTapEditor";
+
+export { TipTapEditor };
diff --git a/apps/space/components/views/project-details.tsx b/apps/space/components/views/project-details.tsx
index 1ef870dc4a..8f46af79c1 100644
--- a/apps/space/components/views/project-details.tsx
+++ b/apps/space/components/views/project-details.tsx
@@ -14,12 +14,23 @@ import { useMobxStore } from "lib/mobx/store-provider";
export const ProjectDetailsView = observer(() => {
const router = useRouter();
- const { workspace_slug, project_slug, states, labels, priorities } = router.query;
+ const { workspace_slug, project_slug, states, labels, priorities, board, peekId } = router.query;
- const { issue: issueStore, project: projectStore, issueDetails: issueDetailStore }: RootStore = useMobxStore();
+ const {
+ issue: issueStore,
+ project: projectStore,
+ issueDetails: issueDetailStore,
+ user: userStore,
+ }: RootStore = useMobxStore();
const activeIssueId = issueDetailStore.peekId;
+ useEffect(() => {
+ if (!userStore.currentUser) {
+ userStore.fetchCurrentUser();
+ }
+ }, [userStore]);
+
useEffect(() => {
if (workspace_slug && project_slug) {
const params = {
@@ -31,11 +42,29 @@ export const ProjectDetailsView = observer(() => {
}
}, [workspace_slug, project_slug, issueStore, states, labels, priorities]);
+ useEffect(() => {
+ if (peekId && workspace_slug && project_slug) {
+ issueDetailStore.setPeekId(peekId.toString());
+ }
+ }, [peekId, issueDetailStore, project_slug, workspace_slug]);
+
+ const handlePeekClose = () => {
+ issueDetailStore.setPeekId(null);
+ router.replace(
+ {
+ pathname: `/${workspace_slug?.toString()}/${project_slug}`,
+ query: {
+ ...(board && { board: board.toString() }),
+ },
+ },
+ undefined,
+ { shallow: true }
+ );
+ };
+
return (
- {workspace_slug && (
-
issueDetailStore.setPeekId(null)} />
- )}
+ {workspace_slug && }
{issueStore?.loader && !issueStore.issues ? (
Loading...
diff --git a/apps/space/pages/index.tsx b/apps/space/pages/index.tsx
index ae93b1ba30..3a8838b1de 100644
--- a/apps/space/pages/index.tsx
+++ b/apps/space/pages/index.tsx
@@ -1,7 +1,157 @@
-import React from "react";
+import React, { useEffect } from "react";
+import Image from "next/image";
+import { useRouter } from "next/router";
+// assets
+import BluePlaneLogoWithoutText from "public/plane-logos/blue-without-text.png";
+// mobx
+import { observer } from "mobx-react-lite";
+import { useMobxStore } from "lib/mobx/store-provider";
+// services
+import authenticationService from "services/authentication.service";
+// hooks
+import useToast from "hooks/use-toast";
+// components
+import { EmailPasswordForm, GithubLoginButton, GoogleLoginButton, EmailCodeForm } from "components/accounts";
-const HomePage = () => (
- Plane Deploy
-);
+const HomePage = () => {
+ const { user: userStore } = useMobxStore();
+
+ const router = useRouter();
+ const { next_path = "/" } = router.query;
+
+ const { setToastAlert } = useToast();
+
+ const onSignInError = (error: any) => {
+ setToastAlert({
+ title: "Error signing in!",
+ type: "error",
+ message: error?.error || "Something went wrong. Please try again later or contact the support team.",
+ });
+ };
+
+ const onSignInSuccess = (response: any) => {
+ const isOnboarded = response?.user?.onboarding_step?.profile_complete || false;
+
+ userStore.setCurrentUser(response?.user);
+
+ if (!isOnboarded) {
+ router.push(`/onboarding?next_path=${next_path}`);
+ return;
+ }
+ console.log("hello");
+ router.push(next_path.toString());
+ };
+
+ const handleGoogleSignIn = async ({ clientId, credential }: any) => {
+ try {
+ if (clientId && credential) {
+ const socialAuthPayload = {
+ medium: "google",
+ credential,
+ clientId,
+ };
+ const response = await authenticationService.socialAuth(socialAuthPayload);
+
+ onSignInSuccess(response);
+ } else {
+ throw Error("Cant find credentials");
+ }
+ } catch (err: any) {
+ onSignInError(err);
+ }
+ };
+
+ const handleGitHubSignIn = async (credential: string) => {
+ try {
+ if (process.env.NEXT_PUBLIC_GITHUB_ID && credential) {
+ const socialAuthPayload = {
+ medium: "github",
+ credential,
+ clientId: process.env.NEXT_PUBLIC_GITHUB_ID,
+ };
+ const response = await authenticationService.socialAuth(socialAuthPayload);
+ onSignInSuccess(response);
+ } else {
+ throw Error("Cant find credentials");
+ }
+ } catch (err: any) {
+ onSignInError(err);
+ }
+ };
+
+ const handlePasswordSignIn = async (formData: any) => {
+ await authenticationService
+ .emailLogin(formData)
+ .then((response) => {
+ try {
+ if (response) {
+ onSignInSuccess(response);
+ }
+ } catch (err: any) {
+ onSignInError(err);
+ }
+ })
+ .catch((err) => onSignInError(err));
+ };
+
+ const handleEmailCodeSignIn = async (response: any) => {
+ try {
+ if (response) {
+ onSignInSuccess(response);
+ }
+ } catch (err: any) {
+ onSignInError(err);
+ }
+ };
+
+ return (
+
+
+
+
+
+ {parseInt(process.env.NEXT_PUBLIC_ENABLE_OAUTH || "0") ? (
+ <>
+
+ Sign in to Plane
+
+
+ >
+ ) : (
+
+ )}
+
+ {parseInt(process.env.NEXT_PUBLIC_ENABLE_OAUTH || "0") ? (
+
+ By signing up, you agree to the{" "}
+
+ Terms & Conditions
+
+
+ ) : null}
+
+
+
+ );
+};
export default HomePage;
diff --git a/apps/space/store/issue_details.ts b/apps/space/store/issue_details.ts
index 4da937bff2..89b2c2c8fd 100644
--- a/apps/space/store/issue_details.ts
+++ b/apps/space/store/issue_details.ts
@@ -13,10 +13,20 @@ export interface IIssueDetailStore {
peekId: string | null;
peekMode: IPeekMode;
details: any;
- // actions
+ // peek actions
setPeekId: (issueId: string | null) => void;
setPeekMode: (mode: IPeekMode) => void;
+ // issue details
fetchIssueDetails: (workspaceId: string, projectId: string, issueId: string) => void;
+ // issue comments
+ addIssueComment: (workspaceId: string, projectId: string, issueId: string, data: any) => void;
+ deleteIssueComment: (workspaceId: string, projectId: string, issueId: string) => void;
+ // issue reactions
+ addIssueReaction: (workspaceId: string, projectId: string, issueId: string) => void;
+ removeIssueReaction: (workspaceId: string, projectId: string, issueId: string) => void;
+ // issue votes
+ addIssueVote: (workspaceId: string, projectId: string, issueId: string) => void;
+ removeIssueVote: (workspaceId: string, projectId: string, issueId: string) => void;
}
class IssueDetailStore implements IssueDetailStore {
@@ -59,9 +69,7 @@ class IssueDetailStore implements IssueDetailStore {
this.error = null;
const issueDetails = this.rootStore.issue.issues?.find((i) => i.id === issueId);
- const reactionsResponse = await this.issueService.getIssueReactions(workspaceSlug, projectId, issueId);
const commentsResponse = await this.issueService.getIssueComments(workspaceSlug, projectId, issueId);
- const votesResponse = await this.issueService.getIssueVotes(workspaceSlug, projectId, issueId);
if (issueDetails) {
runInAction(() => {
@@ -70,8 +78,6 @@ class IssueDetailStore implements IssueDetailStore {
[issueId]: {
...issueDetails,
comments: commentsResponse,
- reactions: reactionsResponse,
- votes: votesResponse,
},
};
});
@@ -79,20 +85,148 @@ class IssueDetailStore implements IssueDetailStore {
} catch (error) {
this.loader = false;
this.error = error;
+ }
+ };
+ addIssueComment = async (workspaceSlug: string, projectId: string, issueId: string, data: any) => {
+ try {
const issueDetails = this.rootStore.issue.issues?.find((i) => i.id === issueId);
+ const issueCommentResponse = await this.issueService.createIssueComment(workspaceSlug, projectId, issueId, data);
+ console.log("issueCommentResponse", issueCommentResponse);
+ if (issueDetails) {
+ runInAction(() => {
+ this.details = {
+ ...this.details,
+ [issueId]: {
+ ...issueDetails,
+ comments: [...this.details[issueId].comments, issueCommentResponse],
+ },
+ };
+ });
+ }
+ return issueCommentResponse;
+ } catch (error) {
+ console.log("Failed to add issue comment");
+ throw error;
+ }
+ };
- runInAction(() => {
- this.details = {
- ...this.details,
- [issueId]: {
- ...issueDetails,
- comments: [],
- reactions: [],
- votes: [],
- },
- };
- });
+ updateIssueComment = async (workspaceSlug: string, projectId: string, issueId: string, data: any) => {
+ try {
+ const issueVoteResponse = await this.issueService.updateIssueComment(workspaceSlug, projectId, issueId, data);
+ if (issueVoteResponse) {
+ runInAction(() => {
+ this.details = {
+ ...this.details,
+ [issueId]: {
+ ...issueDetails,
+ comments: commentsResponse,
+ },
+ };
+ });
+ }
+ } catch (error) {
+ console.log("Failed to add issue comment");
+ }
+ };
+
+ deleteIssueComment = async () => {
+ try {
+ const issueVoteResponse = await this.issueService.deleteIssueComment(workspaceSlug, projectId, issueId, data);
+ // const issueDetails = await this.issueService.fetchIssueDetails(workspaceSlug, projectId, issueId);
+
+ if (issueVoteResponse) {
+ runInAction(() => {
+ this.details = {
+ ...this.details,
+ [issueId]: {
+ ...issueDetails,
+ },
+ };
+ });
+ }
+ } catch (error) {
+ console.log("Failed to add issue vote");
+ }
+ };
+
+ addIssueReaction = async () => {
+ try {
+ const issueVoteResponse = await this.issueService.createIssueReaction(workspaceSlug, projectId, issueId, data);
+ // const issueDetails = await this.issueService.fetchIssueDetails(workspaceSlug, projectId, issueId);
+
+ if (issueVoteResponse) {
+ runInAction(() => {
+ this.details = {
+ ...this.details,
+ [issueId]: {
+ ...issueDetails,
+ },
+ };
+ });
+ }
+ } catch (error) {
+ console.log("Failed to add issue vote");
+ }
+ };
+
+ removeIssueReaction = async () => {
+ try {
+ const issueVoteResponse = await this.issueService.deleteIssueReaction(workspaceSlug, projectId, issueId, data);
+ // const issueDetails = await this.issueService.fetchIssueDetails(workspaceSlug, projectId, issueId);
+
+ if (issueVoteResponse) {
+ runInAction(() => {
+ this.details = {
+ ...this.details,
+ [issueId]: {
+ ...issueDetails,
+ },
+ };
+ });
+ }
+ } catch (error) {
+ console.log("Failed to add issue vote");
+ }
+ };
+
+ addIssueVote = async (workspaceSlug: string, projectId: string, issueId: string, data: { vote: 1 | -1 }) => {
+ try {
+ const issueVoteResponse = await this.issueService.createIssueVote(workspaceSlug, projectId, issueId, data);
+ // const issueDetails = await this.issueService.fetchIssueDetails(workspaceSlug, projectId, issueId);
+
+ if (issueVoteResponse) {
+ runInAction(() => {
+ this.details = {
+ ...this.details,
+ [issueId]: {
+ ...issueDetails,
+ },
+ };
+ });
+ }
+ } catch (error) {
+ console.log("Failed to add issue vote");
+ }
+ };
+
+ removeIssueVote = async (workspaceSlug: string, projectId: string, issueId: string) => {
+ try {
+ const issueVoteResponse = await this.issueService.deleteIssueVote(workspaceSlug, projectId, issueId, data);
+ // const issueDetails = await this.issueService.fetchIssueDetails(workspaceSlug, projectId, issueId);
+
+ if (issueVoteResponse) {
+ runInAction(() => {
+ this.details = {
+ ...this.details,
+ [issueId]: {
+ ...issueDetails,
+ },
+ };
+ });
+ }
+ } catch (error) {
+ console.log("Failed to remove issue vote");
}
};
}
diff --git a/apps/space/store/project.ts b/apps/space/store/project.ts
index a22a58a0c7..45ce06f725 100644
--- a/apps/space/store/project.ts
+++ b/apps/space/store/project.ts
@@ -10,7 +10,7 @@ export interface IProjectStore {
error: any | null;
workspace: IWorkspace | null;
project: IProject | null;
- projectDeploySettings: IProjectSettings | null;
+ deploySettings: IProjectSettings | null;
viewOptions: any;
activeBoard: string | null;
fetchProjectSettings: (workspace_slug: string, project_slug: string) => Promise;
@@ -23,7 +23,7 @@ class ProjectStore implements IProjectStore {
// data
workspace: IWorkspace | null = null;
project: IProject | null = null;
- projectDeploySettings: IProjectSettings | null = null;
+ deploySettings: IProjectSettings | null = null;
viewOptions: any = null;
activeBoard: string | null = null;
// root store
@@ -39,7 +39,7 @@ class ProjectStore implements IProjectStore {
// observable
workspace: observable.ref,
project: observable.ref,
- projectDeploySettings: observable.ref,
+ deploySettings: observable.ref,
viewOptions: observable.ref,
activeBoard: observable.ref,
// actions
@@ -63,10 +63,12 @@ class ProjectStore implements IProjectStore {
const _project: IProject = { ...response?.project_details };
const _workspace: IWorkspace = { ...response?.workspace_detail };
const _viewOptions = { ...response?.views };
+ const _deploySettings = { ...response };
runInAction(() => {
this.project = _project;
this.workspace = _workspace;
this.viewOptions = _viewOptions;
+ this.deploySettings = _deploySettings;
this.loader = false;
});
}
diff --git a/apps/space/store/user.ts b/apps/space/store/user.ts
index d2f68360ff..9cd25bf8cb 100644
--- a/apps/space/store/user.ts
+++ b/apps/space/store/user.ts
@@ -2,8 +2,11 @@
import { observable, action, computed, makeObservable, runInAction } from "mobx";
// service
import UserService from "services/user.service";
-// types
-import { IUserStore } from "../types";
+
+export interface IUserStore {
+ currentUser: any | null;
+ fetchCurrentUser: () => void;
+}
class UserStore implements IUserStore {
currentUser: any | null = null;
@@ -42,7 +45,7 @@ class UserStore implements IUserStore {
return;
}
- this.getUserAsync()
+ this.fetchCurrentUser()
.then(() => {
if (!this.currentUser) {
const currentPath = window.location.pathname;
@@ -55,7 +58,7 @@ class UserStore implements IUserStore {
});
};
- getUserAsync = async () => {
+ fetchCurrentUser = async () => {
try {
const response = await this.userService.currentUser();
if (response) {
@@ -64,10 +67,7 @@ class UserStore implements IUserStore {
});
}
} catch (error) {
- console.error("error", error);
- runInAction(() => {
- // render error actions
- });
+ console.error("Failed to fetch current user", error);
}
};
}
diff --git a/apps/space/types/user.ts b/apps/space/types/user.ts
index 0293c53816..e69de29bb2 100644
--- a/apps/space/types/user.ts
+++ b/apps/space/types/user.ts
@@ -1,4 +0,0 @@
-export interface IUserStore {
- currentUser: any | null;
- getUserAsync: () => void;
-}