forked from github/plane
refactor: project card component refactor
This commit is contained in:
parent
2b419c02a5
commit
310a2ca904
66
web/components/project/card-list.tsx
Normal file
66
web/components/project/card-list.tsx
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import { FC } from "react";
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
|
// lib
|
||||||
|
import { useMobxStore } from "lib/mobx/store-provider";
|
||||||
|
// components
|
||||||
|
import { ProjectCard } from "components/project";
|
||||||
|
import { Loader, EmptyState } from "components/ui";
|
||||||
|
// images
|
||||||
|
import emptyProject from "public/empty-state/project.svg";
|
||||||
|
// icons
|
||||||
|
import { Plus } from "lucide-react";
|
||||||
|
|
||||||
|
export interface IProjectCardList {
|
||||||
|
workspaceSlug: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ProjectCardList: FC<IProjectCardList> = observer((props) => {
|
||||||
|
const { workspaceSlug } = props;
|
||||||
|
// store
|
||||||
|
const { project: projectStore } = useMobxStore();
|
||||||
|
|
||||||
|
const projects = workspaceSlug ? projectStore.projects[workspaceSlug.toString()] : null;
|
||||||
|
|
||||||
|
if (!projects) {
|
||||||
|
return (
|
||||||
|
<Loader className="grid grid-cols-3 gap-4">
|
||||||
|
<Loader.Item height="100px" />
|
||||||
|
<Loader.Item height="100px" />
|
||||||
|
<Loader.Item height="100px" />
|
||||||
|
<Loader.Item height="100px" />
|
||||||
|
<Loader.Item height="100px" />
|
||||||
|
<Loader.Item height="100px" />
|
||||||
|
</Loader>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{projects.length > 0 ? (
|
||||||
|
<div className="h-full p-8 overflow-y-auto">
|
||||||
|
<div className="grid grid-cols-1 gap-9 md:grid-cols-2 lg:grid-cols-3">
|
||||||
|
{projectStore.searchedProjects.map((project) => (
|
||||||
|
<ProjectCard key={project.id} project={project} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<EmptyState
|
||||||
|
image={emptyProject}
|
||||||
|
title="No projects yet"
|
||||||
|
description="Get started by creating your first project"
|
||||||
|
primaryButton={{
|
||||||
|
icon: <Plus className="h-4 w-4" />,
|
||||||
|
text: "New Project",
|
||||||
|
onClick: () => {
|
||||||
|
const e = new KeyboardEvent("keydown", {
|
||||||
|
key: "p",
|
||||||
|
});
|
||||||
|
document.dispatchEvent(e);
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
});
|
@ -1,18 +1,16 @@
|
|||||||
import React from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
import { mutate } from "swr";
|
import { mutate } from "swr";
|
||||||
|
import { observer } from "mobx-react-lite";
|
||||||
|
// icons
|
||||||
|
import { CalendarDaysIcon, LinkIcon, PencilIcon, PlusIcon, StarIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||||
// services
|
// services
|
||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
// hooks
|
// hooks
|
||||||
import useToast from "hooks/use-toast";
|
import useToast from "hooks/use-toast";
|
||||||
// ui
|
// ui
|
||||||
import { CustomMenu, Tooltip } from "components/ui";
|
import { CustomMenu, Tooltip } from "components/ui";
|
||||||
// icons
|
|
||||||
import { CalendarDaysIcon, LinkIcon, PencilIcon, PlusIcon, StarIcon, TrashIcon } from "@heroicons/react/24/outline";
|
|
||||||
// helpers
|
// helpers
|
||||||
import { renderShortDateWithYearFormat } from "helpers/date-time.helper";
|
import { renderShortDateWithYearFormat } from "helpers/date-time.helper";
|
||||||
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
import { copyTextToClipboard, truncateText } from "helpers/string.helper";
|
||||||
@ -21,18 +19,23 @@ import { renderEmoji } from "helpers/emoji.helper";
|
|||||||
import type { IProject } from "types";
|
import type { IProject } from "types";
|
||||||
// fetch-keys
|
// fetch-keys
|
||||||
import { PROJECTS_LIST } from "constants/fetch-keys";
|
import { PROJECTS_LIST } from "constants/fetch-keys";
|
||||||
|
// components
|
||||||
|
import { DeleteProjectModal, JoinProjectModal } from "components/project";
|
||||||
|
|
||||||
export type ProjectCardProps = {
|
export type ProjectCardProps = {
|
||||||
project: IProject;
|
project: IProject;
|
||||||
setToJoinProject: (id: string | null) => void;
|
|
||||||
setDeleteProject: (id: string | null) => void;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SingleProjectCard: React.FC<ProjectCardProps> = ({ project, setToJoinProject, setDeleteProject }) => {
|
export const ProjectCard: React.FC<ProjectCardProps> = observer((props) => {
|
||||||
|
const { project } = props;
|
||||||
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
// toast
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
// states
|
||||||
|
const [deleteProjectModalOpen, setDeleteProjectModal] = useState(false);
|
||||||
|
const [joinProjectModalOpen, setJoinProjectModal] = useState(false);
|
||||||
|
|
||||||
const isOwner = project.member_role === 20;
|
const isOwner = project.member_role === 20;
|
||||||
const isMember = project.member_role === 15;
|
const isMember = project.member_role === 15;
|
||||||
@ -105,6 +108,22 @@ export const SingleProjectCard: React.FC<ProjectCardProps> = ({ project, setToJo
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{/* Delete Project Modal */}
|
||||||
|
<DeleteProjectModal
|
||||||
|
project={project}
|
||||||
|
isOpen={deleteProjectModalOpen}
|
||||||
|
onClose={() => setDeleteProjectModal(false)}
|
||||||
|
/>
|
||||||
|
{workspaceSlug && (
|
||||||
|
<JoinProjectModal
|
||||||
|
workspaceSlug={workspaceSlug?.toString()}
|
||||||
|
project={project}
|
||||||
|
isOpen={joinProjectModalOpen}
|
||||||
|
handleClose={() => setJoinProjectModal(false)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Card Information */}
|
||||||
<div className="flex flex-col rounded-[10px] bg-custom-background-90 shadow">
|
<div className="flex flex-col rounded-[10px] bg-custom-background-90 shadow">
|
||||||
<Link href={`/${workspaceSlug as string}/projects/${project.id}/issues`}>
|
<Link href={`/${workspaceSlug as string}/projects/${project.id}/issues`}>
|
||||||
<a>
|
<a>
|
||||||
@ -124,7 +143,7 @@ export const SingleProjectCard: React.FC<ProjectCardProps> = ({ project, setToJo
|
|||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setToJoinProject(project.id);
|
setJoinProjectModal(true);
|
||||||
}}
|
}}
|
||||||
className="flex cursor-pointer items-center gap-1 rounded bg-green-600 px-2 py-1 text-xs"
|
className="flex cursor-pointer items-center gap-1 rounded bg-green-600 px-2 py-1 text-xs"
|
||||||
>
|
>
|
||||||
@ -180,7 +199,7 @@ export const SingleProjectCard: React.FC<ProjectCardProps> = ({ project, setToJo
|
|||||||
)}
|
)}
|
||||||
<CustomMenu width="auto" verticalEllipsis>
|
<CustomMenu width="auto" verticalEllipsis>
|
||||||
{isOwner && (
|
{isOwner && (
|
||||||
<CustomMenu.MenuItem onClick={() => setDeleteProject(project.id)}>
|
<CustomMenu.MenuItem onClick={() => setDeleteProjectModal(true)}>
|
||||||
<span className="flex items-center justify-start gap-2">
|
<span className="flex items-center justify-start gap-2">
|
||||||
<TrashIcon className="h-4 w-4" />
|
<TrashIcon className="h-4 w-4" />
|
||||||
<span>Delete project</span>
|
<span>Delete project</span>
|
||||||
@ -216,4 +235,4 @@ export const SingleProjectCard: React.FC<ProjectCardProps> = ({ project, setToJo
|
|||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
});
|
@ -3,10 +3,12 @@ export * from "./delete-project-modal";
|
|||||||
export * from "./sidebar-list";
|
export * from "./sidebar-list";
|
||||||
export * from "./settings-sidebar";
|
export * from "./settings-sidebar";
|
||||||
export * from "./single-integration-card";
|
export * from "./single-integration-card";
|
||||||
export * from "./single-project-card";
|
|
||||||
export * from "./sidebar-list-item";
|
export * from "./sidebar-list-item";
|
||||||
export * from "./leave-project-modal";
|
export * from "./leave-project-modal";
|
||||||
export * from "./member-select";
|
export * from "./member-select";
|
||||||
export * from "./members-select";
|
export * from "./members-select";
|
||||||
export * from "./label-select";
|
export * from "./label-select";
|
||||||
export * from "./priority-select";
|
export * from "./priority-select";
|
||||||
|
export * from "./card-list";
|
||||||
|
export * from "./card";
|
||||||
|
export * from "./join-project-modal";
|
||||||
|
@ -1,26 +1,32 @@
|
|||||||
import React, { useState } from "react";
|
import { useState, Fragment } from "react";
|
||||||
|
|
||||||
// headless ui
|
|
||||||
import { Transition, Dialog } from "@headlessui/react";
|
import { Transition, Dialog } from "@headlessui/react";
|
||||||
// ui
|
// ui
|
||||||
import { PrimaryButton, SecondaryButton } from "components/ui";
|
import { PrimaryButton, SecondaryButton } from "components/ui";
|
||||||
// types
|
// types
|
||||||
import type { IProject } from "types";
|
import type { IProject } from "types";
|
||||||
|
// lib
|
||||||
|
import { useMobxStore } from "lib/mobx/store-provider";
|
||||||
|
|
||||||
// type
|
// type
|
||||||
type TJoinProjectModalProps = {
|
type TJoinProjectModalProps = {
|
||||||
data?: IProject;
|
isOpen: boolean;
|
||||||
onClose: () => void;
|
workspaceSlug: string;
|
||||||
onJoin: () => Promise<void>;
|
project: IProject;
|
||||||
|
handleClose: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const JoinProjectModal: React.FC<TJoinProjectModalProps> = ({ onClose, onJoin, data }) => {
|
export const JoinProjectModal: React.FC<TJoinProjectModalProps> = (props) => {
|
||||||
|
const { handleClose, isOpen, project, workspaceSlug } = props;
|
||||||
|
// store
|
||||||
|
const { project: projectStore } = useMobxStore();
|
||||||
|
// states
|
||||||
const [isJoiningLoading, setIsJoiningLoading] = useState(false);
|
const [isJoiningLoading, setIsJoiningLoading] = useState(false);
|
||||||
|
|
||||||
const handleJoin = () => {
|
const handleJoin = () => {
|
||||||
setIsJoiningLoading(true);
|
setIsJoiningLoading(true);
|
||||||
|
|
||||||
onJoin()
|
projectStore
|
||||||
|
.joinProject(workspaceSlug, [project.id])
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setIsJoiningLoading(false);
|
setIsJoiningLoading(false);
|
||||||
handleClose();
|
handleClose();
|
||||||
@ -30,15 +36,11 @@ export const JoinProjectModal: React.FC<TJoinProjectModalProps> = ({ onClose, on
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
onClose();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Transition.Root show={Boolean(data)} as={React.Fragment}>
|
<Transition.Root show={isOpen} as={Fragment}>
|
||||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||||
<Transition.Child
|
<Transition.Child
|
||||||
as={React.Fragment}
|
as={Fragment}
|
||||||
enter="ease-out duration-300"
|
enter="ease-out duration-300"
|
||||||
enterFrom="opacity-0"
|
enterFrom="opacity-0"
|
||||||
enterTo="opacity-100"
|
enterTo="opacity-100"
|
||||||
@ -52,7 +54,7 @@ export const JoinProjectModal: React.FC<TJoinProjectModalProps> = ({ onClose, on
|
|||||||
<div className="fixed inset-0 z-20 overflow-y-auto">
|
<div className="fixed inset-0 z-20 overflow-y-auto">
|
||||||
<div className="flex min-h-full items-center justify-center p-4 text-center sm:p-0">
|
<div className="flex min-h-full items-center justify-center p-4 text-center sm:p-0">
|
||||||
<Transition.Child
|
<Transition.Child
|
||||||
as={React.Fragment}
|
as={Fragment}
|
||||||
enter="ease-out duration-300"
|
enter="ease-out duration-300"
|
||||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||||
@ -62,15 +64,11 @@ export const JoinProjectModal: React.FC<TJoinProjectModalProps> = ({ onClose, on
|
|||||||
>
|
>
|
||||||
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-custom-background-100 border border-custom-border-300 px-5 py-8 text-left shadow-xl transition-all sm:w-full sm:max-w-xl sm:p-6">
|
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-custom-background-100 border border-custom-border-300 px-5 py-8 text-left shadow-xl transition-all sm:w-full sm:max-w-xl sm:p-6">
|
||||||
<div className="space-y-5">
|
<div className="space-y-5">
|
||||||
<Dialog.Title
|
<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-custom-text-100">
|
||||||
as="h3"
|
|
||||||
className="text-lg font-medium leading-6 text-custom-text-100"
|
|
||||||
>
|
|
||||||
Join Project?
|
Join Project?
|
||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
<p>
|
<p>
|
||||||
Are you sure you want to join{" "}
|
Are you sure you want to join <span className="font-semibold">{project?.name}</span>?
|
||||||
<span className="font-semibold">{data?.name}</span>?
|
|
||||||
</p>
|
</p>
|
||||||
<div className="space-y-3" />
|
<div className="space-y-3" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -34,12 +34,11 @@ export const ProjectSidebarList: FC = observer(() => {
|
|||||||
// swr
|
// swr
|
||||||
useSWR(
|
useSWR(
|
||||||
workspaceSlug ? "PROJECTS_LIST" : null,
|
workspaceSlug ? "PROJECTS_LIST" : null,
|
||||||
workspaceSlug ? () => workspaceStore.getWorkspaceProjects(workspaceSlug?.toString()) : null
|
workspaceSlug ? () => projectStore.fetchProjects(workspaceSlug?.toString()) : null
|
||||||
);
|
);
|
||||||
// states
|
// states
|
||||||
const [isFavoriteProjectCreate, setIsFavoriteProjectCreate] = useState(false);
|
const [isFavoriteProjectCreate, setIsFavoriteProjectCreate] = useState(false);
|
||||||
const [isProjectModalOpen, setIsProjectModalOpen] = useState(false);
|
const [isProjectModalOpen, setIsProjectModalOpen] = useState(false);
|
||||||
const [deleteProjectModal, setDeleteProjectModal] = useState(false);
|
|
||||||
|
|
||||||
const [isScrolled, setIsScrolled] = useState(false); // scroll animation state
|
const [isScrolled, setIsScrolled] = useState(false); // scroll animation state
|
||||||
|
|
||||||
@ -48,8 +47,8 @@ export const ProjectSidebarList: FC = observer(() => {
|
|||||||
const { user } = useUserAuth();
|
const { user } = useUserAuth();
|
||||||
const { setToastAlert } = useToast();
|
const { setToastAlert } = useToast();
|
||||||
|
|
||||||
const joinedProjects = workspaceSlug && workspaceStore.workspaceJoinedProjects;
|
const joinedProjects = workspaceSlug && projectStore.joinedProjects;
|
||||||
const favoriteProjects = workspaceSlug && workspaceStore.workspaceFavoriteProjects;
|
const favoriteProjects = workspaceSlug && projectStore.favoriteProjects;
|
||||||
|
|
||||||
const orderedJoinedProjects: IProject[] | undefined = joinedProjects
|
const orderedJoinedProjects: IProject[] | undefined = joinedProjects
|
||||||
? orderArrayBy(joinedProjects, "sort_order", "ascending")
|
? orderArrayBy(joinedProjects, "sort_order", "ascending")
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
import { mutate } from "swr";
|
import { mutate } from "swr";
|
||||||
|
import type { NextPage } from "next";
|
||||||
// services
|
// services
|
||||||
import projectService from "services/project.service";
|
import projectService from "services/project.service";
|
||||||
// hooks
|
// hooks
|
||||||
@ -12,48 +10,26 @@ import useWorkspaces from "hooks/use-workspaces";
|
|||||||
import useUserAuth from "hooks/use-user-auth";
|
import useUserAuth from "hooks/use-user-auth";
|
||||||
// layouts
|
// layouts
|
||||||
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
import { WorkspaceAuthorizationLayout } from "layouts/auth-layout";
|
||||||
// components
|
|
||||||
import { JoinProjectModal } from "components/project/join-project-modal";
|
|
||||||
import { DeleteProjectModal, SingleProjectCard } from "components/project";
|
|
||||||
// ui
|
// ui
|
||||||
import { EmptyState, Icon, Loader, PrimaryButton } from "components/ui";
|
import { Icon, PrimaryButton } from "components/ui";
|
||||||
import { Breadcrumbs, BreadcrumbItem } from "components/breadcrumbs";
|
import { Breadcrumbs, BreadcrumbItem } from "components/breadcrumbs";
|
||||||
// icons
|
// icons
|
||||||
import { PlusIcon } from "@heroicons/react/24/outline";
|
import { PlusIcon } from "@heroicons/react/24/outline";
|
||||||
// images
|
|
||||||
import emptyProject from "public/empty-state/project.svg";
|
|
||||||
// types
|
|
||||||
import type { NextPage } from "next";
|
|
||||||
// fetch-keys
|
|
||||||
import { PROJECT_MEMBERS } from "constants/fetch-keys";
|
|
||||||
// helper
|
// helper
|
||||||
import { truncateText } from "helpers/string.helper";
|
import { truncateText } from "helpers/string.helper";
|
||||||
// types
|
// lib
|
||||||
import { IProject } from "types";
|
import { useMobxStore } from "lib/mobx/store-provider";
|
||||||
|
// components
|
||||||
|
import { ProjectCardList } from "components/project";
|
||||||
|
|
||||||
const ProjectsPage: NextPage = () => {
|
const ProjectsPage: NextPage = () => {
|
||||||
// router
|
// router
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { workspaceSlug } = router.query;
|
const { workspaceSlug } = router.query;
|
||||||
|
// store
|
||||||
const [query, setQuery] = useState("");
|
const { project: projectStore } = useMobxStore();
|
||||||
|
|
||||||
const { user } = useUserAuth();
|
|
||||||
// context data
|
// context data
|
||||||
const { activeWorkspace } = useWorkspaces();
|
const { activeWorkspace } = useWorkspaces();
|
||||||
const { projects, mutateProjects } = useProjects();
|
|
||||||
// states
|
|
||||||
const [deleteProject, setDeleteProject] = useState<string | null>(null);
|
|
||||||
const [selectedProjectToJoin, setSelectedProjectToJoin] = useState<string | null>(null);
|
|
||||||
|
|
||||||
const filteredProjectList =
|
|
||||||
query === ""
|
|
||||||
? projects
|
|
||||||
: projects?.filter(
|
|
||||||
(project) =>
|
|
||||||
project.name.toLowerCase().includes(query.toLowerCase()) ||
|
|
||||||
project.identifier.toLowerCase().includes(query.toLowerCase())
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WorkspaceAuthorizationLayout
|
<WorkspaceAuthorizationLayout
|
||||||
@ -71,8 +47,8 @@ const ProjectsPage: NextPage = () => {
|
|||||||
<Icon iconName="search" className="!text-xl !leading-5 !text-custom-sidebar-text-400" />
|
<Icon iconName="search" className="!text-xl !leading-5 !text-custom-sidebar-text-400" />
|
||||||
<input
|
<input
|
||||||
className="w-full border-none bg-transparent text-xs text-custom-text-200 focus:outline-none"
|
className="w-full border-none bg-transparent text-xs text-custom-text-200 focus:outline-none"
|
||||||
value={query}
|
value={projectStore.searchQuery}
|
||||||
onChange={(e) => setQuery(e.target.value)}
|
onChange={(e) => projectStore.setSearchQuery(e.target.value)}
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -90,83 +66,7 @@ const ProjectsPage: NextPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<JoinProjectModal
|
{workspaceSlug && <ProjectCardList workspaceSlug={workspaceSlug.toString()} />}
|
||||||
data={projects?.find((item) => item.id === selectedProjectToJoin)}
|
|
||||||
onClose={() => setSelectedProjectToJoin(null)}
|
|
||||||
onJoin={async () => {
|
|
||||||
const project = projects?.find((item) => item.id === selectedProjectToJoin);
|
|
||||||
if (!project) return;
|
|
||||||
|
|
||||||
await projectService
|
|
||||||
.joinProject(workspaceSlug as string, {
|
|
||||||
project_ids: [project.id],
|
|
||||||
})
|
|
||||||
.then(async () => {
|
|
||||||
mutate(PROJECT_MEMBERS(project.id));
|
|
||||||
mutateProjects<IProject[]>(
|
|
||||||
(prevData) =>
|
|
||||||
(prevData ?? []).map((p) => ({
|
|
||||||
...p,
|
|
||||||
is_member: p.id === project.id ? true : p.is_member,
|
|
||||||
})),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
setSelectedProjectToJoin(null);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
setSelectedProjectToJoin(null);
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<DeleteProjectModal
|
|
||||||
isOpen={!!deleteProject}
|
|
||||||
onClose={() => setDeleteProject(null)}
|
|
||||||
data={projects?.find((item) => item.id === deleteProject) ?? null}
|
|
||||||
user={user}
|
|
||||||
/>
|
|
||||||
{filteredProjectList ? (
|
|
||||||
<div className="h-full w-full overflow-hidden">
|
|
||||||
{filteredProjectList.length > 0 ? (
|
|
||||||
<div className="h-full p-8 overflow-y-auto">
|
|
||||||
<div className="grid grid-cols-1 gap-9 md:grid-cols-2 lg:grid-cols-3">
|
|
||||||
{filteredProjectList.map((project) => (
|
|
||||||
<SingleProjectCard
|
|
||||||
key={project.id}
|
|
||||||
project={project}
|
|
||||||
setToJoinProject={setSelectedProjectToJoin}
|
|
||||||
setDeleteProject={setDeleteProject}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<EmptyState
|
|
||||||
image={emptyProject}
|
|
||||||
title="No projects yet"
|
|
||||||
description="Get started by creating your first project"
|
|
||||||
primaryButton={{
|
|
||||||
icon: <PlusIcon className="h-4 w-4" />,
|
|
||||||
text: "New Project",
|
|
||||||
onClick: () => {
|
|
||||||
const e = new KeyboardEvent("keydown", {
|
|
||||||
key: "p",
|
|
||||||
});
|
|
||||||
document.dispatchEvent(e);
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<Loader className="grid grid-cols-3 gap-4">
|
|
||||||
<Loader.Item height="100px" />
|
|
||||||
<Loader.Item height="100px" />
|
|
||||||
<Loader.Item height="100px" />
|
|
||||||
<Loader.Item height="100px" />
|
|
||||||
<Loader.Item height="100px" />
|
|
||||||
<Loader.Item height="100px" />
|
|
||||||
</Loader>
|
|
||||||
)}
|
|
||||||
</WorkspaceAuthorizationLayout>
|
</WorkspaceAuthorizationLayout>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -124,8 +124,8 @@ export class ProjectService extends APIService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async joinProject(workspaceSlug: string, data: any): Promise<any> {
|
async joinProject(workspaceSlug: string, project_ids: string[]): Promise<any> {
|
||||||
return this.post(`/api/workspaces/${workspaceSlug}/projects/join/`, data)
|
return this.post(`/api/workspaces/${workspaceSlug}/projects/join/`, { project_ids })
|
||||||
.then((response) => response?.data)
|
.then((response) => response?.data)
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
throw error?.response?.data;
|
throw error?.response?.data;
|
||||||
|
@ -5,12 +5,17 @@ import { RootStore } from "./root";
|
|||||||
import { ProjectService } from "services/project.service";
|
import { ProjectService } from "services/project.service";
|
||||||
import { IssueService } from "services/issue.service";
|
import { IssueService } from "services/issue.service";
|
||||||
import { ICycle } from "types";
|
import { ICycle } from "types";
|
||||||
|
import { CycleService } from "services/cycles.service";
|
||||||
|
|
||||||
export interface ICycleStore {
|
export interface ICycleStore {
|
||||||
loader: boolean;
|
loader: boolean;
|
||||||
error: any | null;
|
error: any | null;
|
||||||
|
|
||||||
cycles: {
|
cycles: {
|
||||||
|
[project_id: string]: ICycle[];
|
||||||
|
};
|
||||||
|
|
||||||
|
cycle_details: {
|
||||||
[cycle_id: string]: ICycle;
|
[cycle_id: string]: ICycle;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -20,6 +25,10 @@ class CycleStore implements ICycleStore {
|
|||||||
error: any | null = null;
|
error: any | null = null;
|
||||||
|
|
||||||
cycles: {
|
cycles: {
|
||||||
|
[project_id: string]: ICycle[];
|
||||||
|
} = {};
|
||||||
|
|
||||||
|
cycle_details: {
|
||||||
[cycle_id: string]: ICycle;
|
[cycle_id: string]: ICycle;
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
@ -28,6 +37,7 @@ class CycleStore implements ICycleStore {
|
|||||||
// services
|
// services
|
||||||
projectService;
|
projectService;
|
||||||
issueService;
|
issueService;
|
||||||
|
cycleService;
|
||||||
|
|
||||||
constructor(_rootStore: RootStore) {
|
constructor(_rootStore: RootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
@ -44,11 +54,37 @@ class CycleStore implements ICycleStore {
|
|||||||
this.rootStore = _rootStore;
|
this.rootStore = _rootStore;
|
||||||
this.projectService = new ProjectService();
|
this.projectService = new ProjectService();
|
||||||
this.issueService = new IssueService();
|
this.issueService = new IssueService();
|
||||||
|
this.cycleService = new CycleService();
|
||||||
}
|
}
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
|
get projectCycles() {
|
||||||
|
if (!this.rootStore.project.projectId) return null;
|
||||||
|
return this.cycles[this.rootStore.project.projectId] || null;
|
||||||
|
}
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
|
fetchCycles = async (workspaceSlug: string, projectSlug: string) => {
|
||||||
|
try {
|
||||||
|
this.loader = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
const cyclesResponse = await this.cycleService.getCyclesWithParams(workspaceSlug, projectSlug, "all");
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.cycles = {
|
||||||
|
...this.cycles,
|
||||||
|
[projectSlug]: cyclesResponse,
|
||||||
|
};
|
||||||
|
this.loader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to fetch project cycles in project store", error);
|
||||||
|
this.loader = false;
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CycleStore;
|
export default CycleStore;
|
||||||
|
@ -3,15 +3,24 @@ import { action, computed, observable, makeObservable, runInAction } from "mobx"
|
|||||||
import { RootStore } from "./root";
|
import { RootStore } from "./root";
|
||||||
// services
|
// services
|
||||||
import { ProjectService } from "services/project.service";
|
import { ProjectService } from "services/project.service";
|
||||||
import { IssueService } from "services/issue.service";
|
import { ModuleService } from "services/modules.service";
|
||||||
|
import { IModule } from "@/types";
|
||||||
|
|
||||||
export interface IModuleStore {
|
export interface IModuleStore {
|
||||||
loader: boolean;
|
loader: boolean;
|
||||||
error: any | null;
|
error: any | null;
|
||||||
|
|
||||||
moduleId: string | null;
|
moduleId: string | null;
|
||||||
|
modules: {
|
||||||
|
[project_id: string]: IModule[];
|
||||||
|
};
|
||||||
|
module_details: {
|
||||||
|
[module_id: string]: IModule;
|
||||||
|
};
|
||||||
|
|
||||||
setModuleId: (moduleSlug: string) => void;
|
setModuleId: (moduleSlug: string) => void;
|
||||||
|
|
||||||
|
fetchModules: (workspaceSlug: string, projectSlug: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ModuleStore implements IModuleStore {
|
class ModuleStore implements IModuleStore {
|
||||||
@ -20,11 +29,19 @@ class ModuleStore implements IModuleStore {
|
|||||||
|
|
||||||
moduleId: string | null = null;
|
moduleId: string | null = null;
|
||||||
|
|
||||||
|
modules: {
|
||||||
|
[project_id: string]: IModule[];
|
||||||
|
} = {};
|
||||||
|
|
||||||
|
module_details: {
|
||||||
|
[module_id: string]: IModule;
|
||||||
|
} = {};
|
||||||
|
|
||||||
// root store
|
// root store
|
||||||
rootStore;
|
rootStore;
|
||||||
// services
|
// services
|
||||||
projectService;
|
projectService;
|
||||||
issueService;
|
moduleService;
|
||||||
|
|
||||||
constructor(_rootStore: RootStore) {
|
constructor(_rootStore: RootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
@ -41,15 +58,41 @@ class ModuleStore implements IModuleStore {
|
|||||||
|
|
||||||
this.rootStore = _rootStore;
|
this.rootStore = _rootStore;
|
||||||
this.projectService = new ProjectService();
|
this.projectService = new ProjectService();
|
||||||
this.issueService = new IssueService();
|
this.moduleService = new ModuleService();
|
||||||
}
|
}
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
|
get projectModules() {
|
||||||
|
if (!this.rootStore.project.projectId) return null;
|
||||||
|
return this.modules[this.rootStore.project.projectId] || null;
|
||||||
|
}
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
setModuleId = (moduleSlug: string) => {
|
setModuleId = (moduleSlug: string) => {
|
||||||
this.moduleId = moduleSlug ?? null;
|
this.moduleId = moduleSlug ?? null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fetchModules = async (workspaceSlug: string, projectSlug: string) => {
|
||||||
|
try {
|
||||||
|
this.loader = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
const modulesResponse = await this.moduleService.getModules(workspaceSlug, projectSlug);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.modules = {
|
||||||
|
...this.modules,
|
||||||
|
[projectSlug]: modulesResponse,
|
||||||
|
};
|
||||||
|
this.loader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to fetch modules list in project store", error);
|
||||||
|
this.loader = false;
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ModuleStore;
|
export default ModuleStore;
|
||||||
|
104
web/store/page.ts
Normal file
104
web/store/page.ts
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import { observable, action, computed, makeObservable, runInAction } from "mobx";
|
||||||
|
// types
|
||||||
|
import { RootStore } from "./root";
|
||||||
|
import { IProject, IIssueLabels, IProjectMember, IStateResponse, IState, IPage } from "types";
|
||||||
|
// services
|
||||||
|
import { ProjectService } from "services/project.service";
|
||||||
|
import { IssueService } from "services/issue.service";
|
||||||
|
import { ProjectStateServices } from "services/project_state.service";
|
||||||
|
import { CycleService } from "services/cycles.service";
|
||||||
|
import { ModuleService } from "services/modules.service";
|
||||||
|
import { ViewService } from "services/views.service";
|
||||||
|
import { PageService } from "services/page.service";
|
||||||
|
|
||||||
|
export interface IPageStore {
|
||||||
|
loader: boolean;
|
||||||
|
error: any | null;
|
||||||
|
|
||||||
|
pageId: string | null;
|
||||||
|
pages: {
|
||||||
|
[project_id: string]: IPage[];
|
||||||
|
};
|
||||||
|
page_details: {
|
||||||
|
[page_id: string]: IPage;
|
||||||
|
};
|
||||||
|
|
||||||
|
//computed
|
||||||
|
projectPages: IPage[];
|
||||||
|
// actions
|
||||||
|
setPageId: (pageId: string) => void;
|
||||||
|
fetchPages: (workspaceSlug: string, projectSlug: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
class PageStore implements IPageStore {
|
||||||
|
loader: boolean = false;
|
||||||
|
error: any | null = null;
|
||||||
|
|
||||||
|
pageId: string | null = null;
|
||||||
|
pages: {
|
||||||
|
[project_id: string]: IPage[];
|
||||||
|
} = {};
|
||||||
|
page_details: {
|
||||||
|
[page_id: string]: IPage;
|
||||||
|
} = {};
|
||||||
|
|
||||||
|
// root store
|
||||||
|
rootStore;
|
||||||
|
// service
|
||||||
|
projectService;
|
||||||
|
pageService;
|
||||||
|
|
||||||
|
constructor(_rootStore: RootStore) {
|
||||||
|
makeObservable(this, {
|
||||||
|
// observable
|
||||||
|
loader: observable,
|
||||||
|
error: observable,
|
||||||
|
|
||||||
|
pageId: observable.ref,
|
||||||
|
pages: observable.ref,
|
||||||
|
|
||||||
|
// computed
|
||||||
|
projectPages: computed,
|
||||||
|
// action
|
||||||
|
setPageId: action,
|
||||||
|
fetchPages: action,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.rootStore = _rootStore;
|
||||||
|
this.projectService = new ProjectService();
|
||||||
|
this.pageService = new PageService();
|
||||||
|
}
|
||||||
|
|
||||||
|
get projectPages() {
|
||||||
|
if (!this.rootStore.project.projectId) return [];
|
||||||
|
return this.pages?.[this.rootStore.project.projectId] || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
setPageId = (pageId: string) => {
|
||||||
|
this.pageId = pageId;
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchPages = async (workspaceSlug: string, projectSlug: string) => {
|
||||||
|
try {
|
||||||
|
this.loader = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
const pagesResponse = await this.pageService.getPagesWithParams(workspaceSlug, projectSlug, "all");
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.pages = {
|
||||||
|
...this.pages,
|
||||||
|
[projectSlug]: pagesResponse,
|
||||||
|
};
|
||||||
|
this.loader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to fetch project pages in project store", error);
|
||||||
|
this.loader = false;
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PageStore;
|
@ -1,7 +1,7 @@
|
|||||||
import { observable, action, computed, makeObservable, runInAction } from "mobx";
|
import { observable, action, computed, makeObservable, runInAction } from "mobx";
|
||||||
// types
|
// types
|
||||||
import { RootStore } from "./root";
|
import { RootStore } from "./root";
|
||||||
import { IProject, IIssueLabels, IProjectMember, IStateResponse, IState, ICycle, IModule, IView, IPage } from "types";
|
import { IProject, IIssueLabels, IProjectMember, IStateResponse, IState } from "types";
|
||||||
// services
|
// services
|
||||||
import { ProjectService } from "services/project.service";
|
import { ProjectService } from "services/project.service";
|
||||||
import { IssueService } from "services/issue.service";
|
import { IssueService } from "services/issue.service";
|
||||||
@ -15,9 +15,10 @@ export interface IProjectStore {
|
|||||||
loader: boolean;
|
loader: boolean;
|
||||||
error: any | null;
|
error: any | null;
|
||||||
|
|
||||||
|
searchQuery: string;
|
||||||
projectId: string | null;
|
projectId: string | null;
|
||||||
|
projects: { [key: string]: IProject[] };
|
||||||
projects: {
|
project_details: {
|
||||||
[projectId: string]: IProject; // projectId: project Info
|
[projectId: string]: IProject; // projectId: project Info
|
||||||
} | null;
|
} | null;
|
||||||
states: {
|
states: {
|
||||||
@ -29,32 +30,26 @@ export interface IProjectStore {
|
|||||||
members: {
|
members: {
|
||||||
[projectId: string]: IProjectMember[] | null; // project_id: members
|
[projectId: string]: IProjectMember[] | null; // project_id: members
|
||||||
} | null;
|
} | null;
|
||||||
cycles: {
|
|
||||||
[projectId: string]: ICycle[] | null; // project_id: cycles
|
|
||||||
} | null;
|
|
||||||
modules: {
|
|
||||||
[projectId: string]: IModule[] | null; // project_id: modules
|
|
||||||
} | null;
|
|
||||||
views: {
|
|
||||||
[projectId: string]: IView[] | null; // project_id: views
|
|
||||||
} | null;
|
|
||||||
pages: {
|
|
||||||
[projectId: string]: IPage[] | null; // project_id: pages
|
|
||||||
} | null;
|
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
|
searchedProjects: IProject[];
|
||||||
projectStatesByGroups: IStateResponse | null;
|
projectStatesByGroups: IStateResponse | null;
|
||||||
projectStates: IState[] | null;
|
projectStates: IState[] | null;
|
||||||
projectLabels: IIssueLabels[] | null;
|
projectLabels: IIssueLabels[] | null;
|
||||||
projectMembers: IProjectMember[] | null;
|
projectMembers: IProjectMember[] | null;
|
||||||
|
|
||||||
|
joinedProjects: IProject[];
|
||||||
|
favoriteProjects: IProject[];
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
setProjectId: (projectId: string) => void;
|
setProjectId: (projectId: string) => void;
|
||||||
|
setSearchQuery: (query: string) => void;
|
||||||
|
|
||||||
getProjectStateById: (stateId: string) => IState | null;
|
getProjectStateById: (stateId: string) => IState | null;
|
||||||
getProjectLabelById: (labelId: string) => IIssueLabels | null;
|
getProjectLabelById: (labelId: string) => IIssueLabels | null;
|
||||||
getProjectMemberById: (memberId: string) => IProjectMember | null;
|
getProjectMemberById: (memberId: string) => IProjectMember | null;
|
||||||
|
|
||||||
|
fetchProjects: (workspaceSlug: string) => Promise<void>;
|
||||||
fetchProjectStates: (workspaceSlug: string, projectSlug: string) => Promise<void>;
|
fetchProjectStates: (workspaceSlug: string, projectSlug: string) => Promise<void>;
|
||||||
fetchProjectLabels: (workspaceSlug: string, projectSlug: string) => Promise<void>;
|
fetchProjectLabels: (workspaceSlug: string, projectSlug: string) => Promise<void>;
|
||||||
fetchProjectMembers: (workspaceSlug: string, projectSlug: string) => Promise<void>;
|
fetchProjectMembers: (workspaceSlug: string, projectSlug: string) => Promise<void>;
|
||||||
@ -65,8 +60,7 @@ export interface IProjectStore {
|
|||||||
orderProjectsWithSortOrder: (sourceIndex: number, destinationIndex: number, projectId: string) => number;
|
orderProjectsWithSortOrder: (sourceIndex: number, destinationIndex: number, projectId: string) => number;
|
||||||
updateProjectView: (workspaceSlug: string, projectId: string, viewProps: any) => Promise<any>;
|
updateProjectView: (workspaceSlug: string, projectId: string, viewProps: any) => Promise<any>;
|
||||||
|
|
||||||
handleProjectLeaveModal: (project: any | null) => void;
|
joinProject: (workspaceSlug: string, projectIds: string[]) => Promise<void>;
|
||||||
|
|
||||||
leaveProject: (workspaceSlug: string, projectSlug: string) => Promise<void>;
|
leaveProject: (workspaceSlug: string, projectSlug: string) => Promise<void>;
|
||||||
deleteProject: (workspaceSlug: string, projectSlug: string) => Promise<void>;
|
deleteProject: (workspaceSlug: string, projectSlug: string) => Promise<void>;
|
||||||
}
|
}
|
||||||
@ -75,26 +69,12 @@ class ProjectStore implements IProjectStore {
|
|||||||
loader: boolean = false;
|
loader: boolean = false;
|
||||||
error: any | null = null;
|
error: any | null = null;
|
||||||
|
|
||||||
projectLeaveModal: boolean = false;
|
searchQuery: string = "";
|
||||||
projectLeaveDetails: IProject | null = null;
|
|
||||||
|
|
||||||
projectId: string | null = null;
|
projectId: string | null = null;
|
||||||
|
projects: { [workspaceSlug: string]: IProject[] } = {}; // workspace_id: project[]
|
||||||
projects: {
|
project_details: {
|
||||||
[key: string]: IProject; // project_id: project
|
[key: string]: IProject; // project_id: project
|
||||||
} | null = {};
|
} | null = {};
|
||||||
cycles: {
|
|
||||||
[key: string]: ICycle[]; // project_id: cycles
|
|
||||||
} = {};
|
|
||||||
modules: {
|
|
||||||
[key: string]: IModule[]; // project_id: modules
|
|
||||||
} = {};
|
|
||||||
views: {
|
|
||||||
[key: string]: IView[]; // project_id: views
|
|
||||||
} = {};
|
|
||||||
pages: {
|
|
||||||
[key: string]: IPage[]; // project_id: pages
|
|
||||||
} = {};
|
|
||||||
states: {
|
states: {
|
||||||
[key: string]: IStateResponse; // project_id: states
|
[key: string]: IStateResponse; // project_id: states
|
||||||
} | null = {};
|
} | null = {};
|
||||||
@ -122,23 +102,27 @@ class ProjectStore implements IProjectStore {
|
|||||||
loader: observable,
|
loader: observable,
|
||||||
error: observable,
|
error: observable,
|
||||||
|
|
||||||
|
searchQuery: observable.ref,
|
||||||
projectId: observable.ref,
|
projectId: observable.ref,
|
||||||
projects: observable.ref,
|
projects: observable.ref,
|
||||||
|
project_details: observable.ref,
|
||||||
states: observable.ref,
|
states: observable.ref,
|
||||||
labels: observable.ref,
|
labels: observable.ref,
|
||||||
members: observable.ref,
|
members: observable.ref,
|
||||||
|
|
||||||
projectLeaveModal: observable,
|
|
||||||
projectLeaveDetails: observable.ref,
|
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
|
searchedProjects: computed,
|
||||||
projectStatesByGroups: computed,
|
projectStatesByGroups: computed,
|
||||||
projectStates: computed,
|
projectStates: computed,
|
||||||
projectLabels: computed,
|
projectLabels: computed,
|
||||||
projectMembers: computed,
|
projectMembers: computed,
|
||||||
|
|
||||||
|
joinedProjects: computed,
|
||||||
|
favoriteProjects: computed,
|
||||||
|
|
||||||
// action
|
// action
|
||||||
setProjectId: action,
|
setProjectId: action,
|
||||||
|
setSearchQuery: action,
|
||||||
|
|
||||||
getProjectStateById: action,
|
getProjectStateById: action,
|
||||||
getProjectLabelById: action,
|
getProjectLabelById: action,
|
||||||
@ -153,8 +137,6 @@ class ProjectStore implements IProjectStore {
|
|||||||
|
|
||||||
orderProjectsWithSortOrder: action,
|
orderProjectsWithSortOrder: action,
|
||||||
updateProjectView: action,
|
updateProjectView: action,
|
||||||
|
|
||||||
handleProjectLeaveModal: action,
|
|
||||||
leaveProject: action,
|
leaveProject: action,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -168,6 +150,30 @@ class ProjectStore implements IProjectStore {
|
|||||||
this.cycleService = new CycleService();
|
this.cycleService = new CycleService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get searchedProjects() {
|
||||||
|
if (!this.rootStore.workspace.workspaceSlug) return [];
|
||||||
|
|
||||||
|
const projects = this.projects[this.rootStore.workspace.workspaceSlug];
|
||||||
|
|
||||||
|
return this.searchQuery === ""
|
||||||
|
? projects
|
||||||
|
: projects?.filter(
|
||||||
|
(project) =>
|
||||||
|
project.name.toLowerCase().includes(this.searchQuery.toLowerCase()) ||
|
||||||
|
project.identifier.toLowerCase().includes(this.searchQuery.toLowerCase())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
get joinedProjects() {
|
||||||
|
if (!this.rootStore.workspace.workspaceSlug) return [];
|
||||||
|
return this.projects?.[this.rootStore.workspace.workspaceSlug]?.filter((p) => p.is_member);
|
||||||
|
}
|
||||||
|
|
||||||
|
get favoriteProjects() {
|
||||||
|
if (!this.rootStore.workspace.workspaceSlug) return [];
|
||||||
|
return this.projects?.[this.rootStore.workspace.workspaceSlug]?.filter((p) => p.is_favorite);
|
||||||
|
}
|
||||||
|
|
||||||
get projectStatesByGroups() {
|
get projectStatesByGroups() {
|
||||||
if (!this.projectId) return null;
|
if (!this.projectId) return null;
|
||||||
return this.states?.[this.projectId] || null;
|
return this.states?.[this.projectId] || null;
|
||||||
@ -196,31 +202,34 @@ class ProjectStore implements IProjectStore {
|
|||||||
return this.members?.[this.projectId] || null;
|
return this.members?.[this.projectId] || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
get projectCycles() {
|
|
||||||
if (!this.projectId) return null;
|
|
||||||
return this.cycles[this.projectId] || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
get projectModules() {
|
|
||||||
if (!this.projectId) return null;
|
|
||||||
return this.modules[this.projectId] || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
get projectViews() {
|
|
||||||
if (!this.projectId) return null;
|
|
||||||
return this.views[this.projectId] || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
get projectPages() {
|
|
||||||
if (!this.projectId) return null;
|
|
||||||
return this.pages[this.projectId] || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
setProjectId = (projectSlug: string) => {
|
setProjectId = (projectSlug: string) => {
|
||||||
this.projectId = projectSlug ?? null;
|
this.projectId = projectSlug ?? null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
setSearchQuery = (query: string) => {
|
||||||
|
this.searchQuery = query;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get Workspace projects using workspace slug
|
||||||
|
* @param workspaceSlug
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
fetchProjects = async (workspaceSlug: string) => {
|
||||||
|
try {
|
||||||
|
const projects = await this.projectService.getProjects(workspaceSlug, { is_favorite: "all" });
|
||||||
|
runInAction(() => {
|
||||||
|
this.projects = {
|
||||||
|
...this.projects,
|
||||||
|
[workspaceSlug]: projects,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Failed to fetch project from workspace store");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
getProjectStateById = (stateId: string) => {
|
getProjectStateById = (stateId: string) => {
|
||||||
if (!this.projectId) return null;
|
if (!this.projectId) return null;
|
||||||
const states = this.projectStates;
|
const states = this.projectStates;
|
||||||
@ -314,99 +323,10 @@ class ProjectStore implements IProjectStore {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchProjectCycles = async (workspaceSlug: string, projectSlug: string) => {
|
|
||||||
try {
|
|
||||||
this.loader = true;
|
|
||||||
this.error = null;
|
|
||||||
|
|
||||||
const cyclesResponse = await this.cycleService.getCyclesWithParams(workspaceSlug, projectSlug, "all");
|
|
||||||
|
|
||||||
runInAction(() => {
|
|
||||||
this.cycles = {
|
|
||||||
...this.cycles,
|
|
||||||
[projectSlug]: cyclesResponse,
|
|
||||||
};
|
|
||||||
this.loader = false;
|
|
||||||
this.error = null;
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to fetch project cycles in project store", error);
|
|
||||||
this.loader = false;
|
|
||||||
this.error = error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchProjectModules = async (workspaceSlug: string, projectSlug: string) => {
|
|
||||||
try {
|
|
||||||
this.loader = true;
|
|
||||||
this.error = null;
|
|
||||||
|
|
||||||
const modulesResponse = await this.moduleService.getModules(workspaceSlug, projectSlug);
|
|
||||||
|
|
||||||
runInAction(() => {
|
|
||||||
this.modules = {
|
|
||||||
...this.modules,
|
|
||||||
[projectSlug]: modulesResponse,
|
|
||||||
};
|
|
||||||
this.loader = false;
|
|
||||||
this.error = null;
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to fetch modules list in project store", error);
|
|
||||||
this.loader = false;
|
|
||||||
this.error = error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchProjectViews = async (workspaceSlug: string, projectSlug: string) => {
|
|
||||||
try {
|
|
||||||
this.loader = true;
|
|
||||||
this.error = null;
|
|
||||||
|
|
||||||
const viewsResponse = await this.viewService.getViews(workspaceSlug, projectSlug);
|
|
||||||
|
|
||||||
runInAction(() => {
|
|
||||||
this.views = {
|
|
||||||
...this.views,
|
|
||||||
[projectSlug]: viewsResponse,
|
|
||||||
};
|
|
||||||
this.loader = false;
|
|
||||||
this.error = null;
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to fetch project views in project store", error);
|
|
||||||
this.loader = false;
|
|
||||||
this.error = error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fetchProjectPages = async (workspaceSlug: string, projectSlug: string) => {
|
|
||||||
try {
|
|
||||||
this.loader = true;
|
|
||||||
this.error = null;
|
|
||||||
|
|
||||||
const pagesResponse = await this.pageService.getPagesWithParams(workspaceSlug, projectSlug, "all");
|
|
||||||
|
|
||||||
runInAction(() => {
|
|
||||||
this.pages = {
|
|
||||||
...this.pages,
|
|
||||||
[projectSlug]: pagesResponse,
|
|
||||||
};
|
|
||||||
this.loader = false;
|
|
||||||
this.error = null;
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Failed to fetch project pages in project store", error);
|
|
||||||
this.loader = false;
|
|
||||||
this.error = error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
addProjectToFavorites = async (workspaceSlug: string, projectId: string) => {
|
addProjectToFavorites = async (workspaceSlug: string, projectId: string) => {
|
||||||
try {
|
try {
|
||||||
const response = await this.projectService.addProjectToFavorites(workspaceSlug, projectId);
|
const response = await this.projectService.addProjectToFavorites(workspaceSlug, projectId);
|
||||||
console.log("res", response);
|
await this.fetchProjects(workspaceSlug);
|
||||||
await this.rootStore.workspace.getWorkspaceProjects(workspaceSlug);
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Failed to add project to favorite");
|
console.log("Failed to add project to favorite");
|
||||||
@ -416,8 +336,8 @@ class ProjectStore implements IProjectStore {
|
|||||||
|
|
||||||
removeProjectFromFavorites = async (workspaceSlug: string, projectId: string) => {
|
removeProjectFromFavorites = async (workspaceSlug: string, projectId: string) => {
|
||||||
try {
|
try {
|
||||||
const response = this.projectService.removeProjectFromFavorites(workspaceSlug, projectId);
|
const response = await this.projectService.removeProjectFromFavorites(workspaceSlug, projectId);
|
||||||
this.rootStore.workspace.getWorkspaceProjects(workspaceSlug);
|
await this.fetchProjects(workspaceSlug);
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Failed to add project to favorite");
|
console.log("Failed to add project to favorite");
|
||||||
@ -430,7 +350,7 @@ class ProjectStore implements IProjectStore {
|
|||||||
const workspaceSlug = this.rootStore.workspace.workspaceSlug;
|
const workspaceSlug = this.rootStore.workspace.workspaceSlug;
|
||||||
if (!workspaceSlug) return 0;
|
if (!workspaceSlug) return 0;
|
||||||
|
|
||||||
const projectsList = this.rootStore.workspace.projects[workspaceSlug] || [];
|
const projectsList = this.projects[workspaceSlug] || [];
|
||||||
let updatedSortOrder = projectsList[sortIndex].sort_order;
|
let updatedSortOrder = projectsList[sortIndex].sort_order;
|
||||||
|
|
||||||
if (destinationIndex === 0) updatedSortOrder = (projectsList[0].sort_order as number) - 1000;
|
if (destinationIndex === 0) updatedSortOrder = (projectsList[0].sort_order as number) - 1000;
|
||||||
@ -451,8 +371,8 @@ class ProjectStore implements IProjectStore {
|
|||||||
);
|
);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.rootStore.workspace.projects = {
|
this.projects = {
|
||||||
...this.rootStore.workspace.projects,
|
...this.projects,
|
||||||
[workspaceSlug]: updatedProjectsList,
|
[workspaceSlug]: updatedProjectsList,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -467,7 +387,8 @@ class ProjectStore implements IProjectStore {
|
|||||||
updateProjectView = async (workspaceSlug: string, projectId: string, viewProps: any) => {
|
updateProjectView = async (workspaceSlug: string, projectId: string, viewProps: any) => {
|
||||||
try {
|
try {
|
||||||
const response = await this.projectService.setProjectView(workspaceSlug, projectId, viewProps);
|
const response = await this.projectService.setProjectView(workspaceSlug, projectId, viewProps);
|
||||||
await this.rootStore.workspace.getWorkspaceProjects(workspaceSlug);
|
await this.fetchProjects(workspaceSlug);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Failed to update sort order of the projects");
|
console.log("Failed to update sort order of the projects");
|
||||||
@ -475,13 +396,24 @@ class ProjectStore implements IProjectStore {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleProjectLeaveModal = (project: IProject | null = null) => {
|
joinProject = async (workspaceSlug: string, projectIds: string[]) => {
|
||||||
if (project && project?.id) {
|
try {
|
||||||
this.projectLeaveModal = !this.projectLeaveModal;
|
this.loader = true;
|
||||||
this.projectLeaveDetails = project;
|
this.error = null;
|
||||||
} else {
|
|
||||||
this.projectLeaveModal = !this.projectLeaveModal;
|
const response = await this.projectService.joinProject(workspaceSlug, projectIds);
|
||||||
this.projectLeaveDetails = null;
|
await this.fetchProjects(workspaceSlug);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.loader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
this.loader = false;
|
||||||
|
this.error = error;
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -491,7 +423,7 @@ class ProjectStore implements IProjectStore {
|
|||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
const response = await this.projectService.leaveProject(workspaceSlug, projectSlug, this.rootStore.user);
|
const response = await this.projectService.leaveProject(workspaceSlug, projectSlug, this.rootStore.user);
|
||||||
await this.rootStore.workspace.getWorkspaceProjects(workspaceSlug);
|
await this.fetchProjects(workspaceSlug);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.loader = false;
|
this.loader = false;
|
||||||
@ -509,7 +441,7 @@ class ProjectStore implements IProjectStore {
|
|||||||
deleteProject = async (workspaceSlug: string, projectId: string) => {
|
deleteProject = async (workspaceSlug: string, projectId: string) => {
|
||||||
try {
|
try {
|
||||||
await this.projectService.deleteProject(workspaceSlug, projectId, this.rootStore.user.currentUser);
|
await this.projectService.deleteProject(workspaceSlug, projectId, this.rootStore.user.currentUser);
|
||||||
await this.rootStore.workspace.getWorkspaceProjects(workspaceSlug);
|
await this.fetchProjects(workspaceSlug);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Failed to delete project from project store");
|
console.log("Failed to delete project from project store");
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,20 @@ import { RootStore } from "./root";
|
|||||||
// services
|
// services
|
||||||
import { ProjectService } from "services/project.service";
|
import { ProjectService } from "services/project.service";
|
||||||
import { IssueService } from "services/issue.service";
|
import { IssueService } from "services/issue.service";
|
||||||
|
import { ViewService } from "services/views.service";
|
||||||
|
|
||||||
export interface IViewStore {
|
export interface IViewStore {
|
||||||
loader: boolean;
|
loader: boolean;
|
||||||
error: any | null;
|
error: any | null;
|
||||||
|
|
||||||
viewId: string | null;
|
viewId: string | null;
|
||||||
|
views: {
|
||||||
|
[project_id: string]: any[];
|
||||||
|
};
|
||||||
|
|
||||||
setViewId: (viewSlug: string) => void;
|
setViewId: (viewSlug: string) => void;
|
||||||
|
|
||||||
|
fetchViews: (workspaceSlug: string, projectSlug: string) => Promise<any>;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewStore implements IViewStore {
|
class ViewStore implements IViewStore {
|
||||||
@ -19,12 +25,15 @@ class ViewStore implements IViewStore {
|
|||||||
error: any | null = null;
|
error: any | null = null;
|
||||||
|
|
||||||
viewId: string | null = null;
|
viewId: string | null = null;
|
||||||
|
views: {
|
||||||
|
[project_id: string]: any[];
|
||||||
|
} = {};
|
||||||
|
|
||||||
// root store
|
// root store
|
||||||
rootStore;
|
rootStore;
|
||||||
// services
|
// services
|
||||||
projectService;
|
projectService;
|
||||||
issueService;
|
viewService;
|
||||||
|
|
||||||
constructor(_rootStore: RootStore) {
|
constructor(_rootStore: RootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
@ -32,24 +41,51 @@ class ViewStore implements IViewStore {
|
|||||||
error: observable.ref,
|
error: observable.ref,
|
||||||
|
|
||||||
viewId: observable.ref,
|
viewId: observable.ref,
|
||||||
|
views: observable.ref,
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
|
projectViews: computed,
|
||||||
// actions
|
// actions
|
||||||
setViewId: action,
|
setViewId: action,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.rootStore = _rootStore;
|
this.rootStore = _rootStore;
|
||||||
this.projectService = new ProjectService();
|
this.projectService = new ProjectService();
|
||||||
this.issueService = new IssueService();
|
this.viewService = new ViewService();
|
||||||
}
|
}
|
||||||
|
|
||||||
// computed
|
// computed
|
||||||
|
get projectViews() {
|
||||||
|
if (!this.rootStore.project.projectId) return null;
|
||||||
|
return this.views[this.rootStore.project.projectId] || null;
|
||||||
|
}
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
setViewId = (viewSlug: string) => {
|
setViewId = (viewSlug: string) => {
|
||||||
this.viewId = viewSlug ?? null;
|
this.viewId = viewSlug ?? null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fetchViews = async (workspaceSlug: string, projectId: string) => {
|
||||||
|
try {
|
||||||
|
this.loader = true;
|
||||||
|
this.error = null;
|
||||||
|
|
||||||
|
const viewsResponse = await this.viewService.getViews(workspaceSlug, projectId);
|
||||||
|
|
||||||
|
runInAction(() => {
|
||||||
|
this.views = {
|
||||||
|
...this.views,
|
||||||
|
[projectId]: viewsResponse,
|
||||||
|
};
|
||||||
|
this.loader = false;
|
||||||
|
this.error = null;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to fetch project views in project store", error);
|
||||||
|
this.loader = false;
|
||||||
|
this.error = error;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ViewStore;
|
export default ViewStore;
|
||||||
|
@ -12,19 +12,15 @@ export interface IWorkspaceStore {
|
|||||||
error: any | null;
|
error: any | null;
|
||||||
// observables
|
// observables
|
||||||
workspaces: IWorkspace[];
|
workspaces: IWorkspace[];
|
||||||
projects: { [key: string]: IProject[] };
|
|
||||||
labels: { [key: string]: IIssueLabels[] } | {}; // workspace_id: labels[]
|
labels: { [key: string]: IIssueLabels[] } | {}; // workspace_id: labels[]
|
||||||
workspaceSlug: string | null;
|
workspaceSlug: string | null;
|
||||||
// computed
|
// computed
|
||||||
currentWorkspace: IWorkspace | null;
|
currentWorkspace: IWorkspace | null;
|
||||||
workspaceLabels: IIssueLabels[];
|
workspaceLabels: IIssueLabels[];
|
||||||
workspaceJoinedProjects: IProject[];
|
|
||||||
workspaceFavoriteProjects: IProject[];
|
|
||||||
// actions
|
// actions
|
||||||
setWorkspaceSlug: (workspaceSlug: string) => void;
|
setWorkspaceSlug: (workspaceSlug: string) => void;
|
||||||
getWorkspaceBySlug: (workspaceSlug: string) => IWorkspace | null;
|
getWorkspaceBySlug: (workspaceSlug: string) => IWorkspace | null;
|
||||||
getWorkspaceLabelById: (workspaceSlug: string, labelId: string) => IIssueLabels | null;
|
getWorkspaceLabelById: (workspaceSlug: string, labelId: string) => IIssueLabels | null;
|
||||||
getWorkspaceProjects: (workspaceSlug: string) => void;
|
|
||||||
fetchWorkspaces: () => Promise<void>;
|
fetchWorkspaces: () => Promise<void>;
|
||||||
fetchWorkspaceLabels: (workspaceSlug: string) => Promise<void>;
|
fetchWorkspaceLabels: (workspaceSlug: string) => Promise<void>;
|
||||||
}
|
}
|
||||||
@ -52,17 +48,13 @@ class WorkspaceStore implements IWorkspaceStore {
|
|||||||
workspaces: observable.ref,
|
workspaces: observable.ref,
|
||||||
labels: observable.ref,
|
labels: observable.ref,
|
||||||
workspaceSlug: observable.ref,
|
workspaceSlug: observable.ref,
|
||||||
projects: observable.ref,
|
|
||||||
// computed
|
// computed
|
||||||
currentWorkspace: computed,
|
currentWorkspace: computed,
|
||||||
workspaceLabels: computed,
|
workspaceLabels: computed,
|
||||||
workspaceJoinedProjects: computed,
|
|
||||||
workspaceFavoriteProjects: computed,
|
|
||||||
// actions
|
// actions
|
||||||
setWorkspaceSlug: action,
|
setWorkspaceSlug: action,
|
||||||
getWorkspaceBySlug: action,
|
getWorkspaceBySlug: action,
|
||||||
getWorkspaceLabelById: action,
|
getWorkspaceLabelById: action,
|
||||||
getWorkspaceProjects: action,
|
|
||||||
fetchWorkspaces: action,
|
fetchWorkspaces: action,
|
||||||
fetchWorkspaceLabels: action,
|
fetchWorkspaceLabels: action,
|
||||||
});
|
});
|
||||||
@ -90,16 +82,6 @@ class WorkspaceStore implements IWorkspaceStore {
|
|||||||
return _labels && Object.keys(_labels).length > 0 ? _labels : [];
|
return _labels && Object.keys(_labels).length > 0 ? _labels : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
get workspaceJoinedProjects() {
|
|
||||||
if (!this.workspaceSlug) return [];
|
|
||||||
return this.projects?.[this.workspaceSlug]?.filter((p) => p.is_member);
|
|
||||||
}
|
|
||||||
|
|
||||||
get workspaceFavoriteProjects() {
|
|
||||||
if (!this.workspaceSlug) return [];
|
|
||||||
return this.projects?.[this.workspaceSlug]?.filter((p) => p.is_favorite);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set workspace slug in the store
|
* set workspace slug in the store
|
||||||
* @param workspaceSlug
|
* @param workspaceSlug
|
||||||
@ -113,25 +95,6 @@ class WorkspaceStore implements IWorkspaceStore {
|
|||||||
*/
|
*/
|
||||||
getWorkspaceBySlug = (workspaceSlug: string) => this.workspaces.find((w) => w.slug == workspaceSlug) || null;
|
getWorkspaceBySlug = (workspaceSlug: string) => this.workspaces.find((w) => w.slug == workspaceSlug) || null;
|
||||||
|
|
||||||
/**
|
|
||||||
* get Workspace projects using workspace slug
|
|
||||||
* @param workspaceSlug
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
getWorkspaceProjects = async (workspaceSlug: string) => {
|
|
||||||
try {
|
|
||||||
const projects = await this.projectService.getProjects(workspaceSlug, { is_favorite: "all" });
|
|
||||||
runInAction(() => {
|
|
||||||
this.projects = {
|
|
||||||
...this.projects,
|
|
||||||
[workspaceSlug]: projects,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.log("Failed to fetch project from workspace store");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get workspace label information from the workspace labels
|
* get workspace label information from the workspace labels
|
||||||
* @param labelId
|
* @param labelId
|
||||||
@ -188,50 +151,6 @@ class WorkspaceStore implements IWorkspaceStore {
|
|||||||
this.error = error;
|
this.error = error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// getMyIssuesAsync = async (workspaceId: string, fetchFilterToggle: boolean = true) => {
|
|
||||||
// try {
|
|
||||||
// this.loader = true;
|
|
||||||
// this.error = null;
|
|
||||||
|
|
||||||
// if (fetchFilterToggle) await this.rootStore.issueFilters.getWorkspaceMyIssuesFilters(workspaceId);
|
|
||||||
// const filteredParams = this.rootStore.issueFilters.getComputedFilters(
|
|
||||||
// workspaceId,
|
|
||||||
// null,
|
|
||||||
// null,
|
|
||||||
// null,
|
|
||||||
// null,
|
|
||||||
// "my_issues"
|
|
||||||
// );
|
|
||||||
// const issuesResponse = await this.userService.userIssues(workspaceId, filteredParams);
|
|
||||||
|
|
||||||
// if (issuesResponse) {
|
|
||||||
// const _issueResponse: any = {
|
|
||||||
// ...this.issues,
|
|
||||||
// [workspaceId]: {
|
|
||||||
// ...this?.issues[workspaceId],
|
|
||||||
// my_issues: {
|
|
||||||
// ...this?.issues[workspaceId]?.my_issues,
|
|
||||||
// [this.rootStore?.issueFilters?.userFilters?.display_filters?.layout as string]: issuesResponse,
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
// };
|
|
||||||
|
|
||||||
// runInAction(() => {
|
|
||||||
// this.issues = _issueResponse;
|
|
||||||
// this.loader = false;
|
|
||||||
// this.error = null;
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return issuesResponse;
|
|
||||||
// } catch (error) {
|
|
||||||
// console.warn("error in fetching the my issues", error);
|
|
||||||
// this.loader = false;
|
|
||||||
// this.error = null;
|
|
||||||
// return error;
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default WorkspaceStore;
|
export default WorkspaceStore;
|
||||||
|
Loading…
Reference in New Issue
Block a user