forked from github/plane
chore: store fixes
This commit is contained in:
parent
2dcaccd4ec
commit
9b41b5baf5
@ -26,110 +26,121 @@ type Props = {
|
|||||||
|
|
||||||
export type TPeekOverviewModes = "side" | "modal" | "full";
|
export type TPeekOverviewModes = "side" | "modal" | "full";
|
||||||
|
|
||||||
export const IssuePeekOverview: React.FC<Props> = observer(
|
export const IssuePeekOverview: React.FC<Props> = observer(({ handleMutation, projectId, readOnly, workspaceSlug }) => {
|
||||||
({ handleMutation, projectId, readOnly, workspaceSlug }) => {
|
const [isSidePeekOpen, setIsSidePeekOpen] = useState(false);
|
||||||
const [isSidePeekOpen, setIsSidePeekOpen] = useState(false);
|
const [isModalPeekOpen, setIsModalPeekOpen] = useState(false);
|
||||||
const [isModalPeekOpen, setIsModalPeekOpen] = useState(false);
|
const [peekOverviewMode, setPeekOverviewMode] = useState<TPeekOverviewModes>("side");
|
||||||
const [peekOverviewMode, setPeekOverviewMode] = useState<TPeekOverviewModes>("side");
|
const [deleteIssueModal, setDeleteIssueModal] = useState(false);
|
||||||
const [deleteIssueModal, setDeleteIssueModal] = useState(false);
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { peekIssue } = router.query;
|
const { peekIssue } = router.query;
|
||||||
|
|
||||||
const { issues: issuesStore } = useMobxStore();
|
const { issueDetail: issueDetailStore } = useMobxStore();
|
||||||
const { deleteIssue, getIssueById, issues, updateIssue } = issuesStore;
|
const { deleteIssue, getIssueById, issues, updateIssue } = issueDetailStore;
|
||||||
|
|
||||||
const issue = issues[peekIssue?.toString() ?? ""];
|
const issue = issues[peekIssue?.toString() ?? ""];
|
||||||
|
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
const { query } = router;
|
const { query } = router;
|
||||||
delete query.peekIssue;
|
delete query.peekIssue;
|
||||||
|
|
||||||
router.push({
|
router.push({
|
||||||
pathname: router.pathname,
|
pathname: router.pathname,
|
||||||
query: { ...query },
|
query: { ...query },
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleUpdateIssue = async (formData: Partial<IIssue>) => {
|
const handleUpdateIssue = async (formData: Partial<IIssue>) => {
|
||||||
if (!issue || !user) return;
|
if (!issue || !user) return;
|
||||||
|
|
||||||
await updateIssue(workspaceSlug, projectId, issue.id, formData, user);
|
await updateIssue(workspaceSlug, projectId, issue.id, formData, user);
|
||||||
mutate(PROJECT_ISSUES_ACTIVITY(issue.id));
|
mutate(PROJECT_ISSUES_ACTIVITY(issue.id));
|
||||||
handleMutation();
|
handleMutation();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteIssue = async () => {
|
const handleDeleteIssue = async () => {
|
||||||
if (!issue || !user) return;
|
if (!issue || !user) return;
|
||||||
|
|
||||||
await deleteIssue(workspaceSlug, projectId, issue.id, user);
|
await deleteIssue(workspaceSlug, projectId, issue.id, user);
|
||||||
handleMutation();
|
handleMutation();
|
||||||
|
|
||||||
handleClose();
|
handleClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!peekIssue) return;
|
if (!peekIssue) return;
|
||||||
|
|
||||||
getIssueById(workspaceSlug, projectId, peekIssue.toString());
|
getIssueById(workspaceSlug, projectId, peekIssue.toString());
|
||||||
}, [getIssueById, peekIssue, projectId, workspaceSlug]);
|
}, [getIssueById, peekIssue, projectId, workspaceSlug]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (peekIssue) {
|
if (peekIssue) {
|
||||||
if (peekOverviewMode === "side") {
|
if (peekOverviewMode === "side") {
|
||||||
setIsSidePeekOpen(true);
|
setIsSidePeekOpen(true);
|
||||||
setIsModalPeekOpen(false);
|
|
||||||
} else {
|
|
||||||
setIsModalPeekOpen(true);
|
|
||||||
setIsSidePeekOpen(false);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
setIsSidePeekOpen(false);
|
|
||||||
setIsModalPeekOpen(false);
|
setIsModalPeekOpen(false);
|
||||||
|
} else {
|
||||||
|
setIsModalPeekOpen(true);
|
||||||
|
setIsSidePeekOpen(false);
|
||||||
}
|
}
|
||||||
}, [peekIssue, peekOverviewMode]);
|
} else {
|
||||||
|
setIsSidePeekOpen(false);
|
||||||
|
setIsModalPeekOpen(false);
|
||||||
|
}
|
||||||
|
}, [peekIssue, peekOverviewMode]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DeleteIssueModal
|
<DeleteIssueModal
|
||||||
isOpen={deleteIssueModal}
|
isOpen={deleteIssueModal}
|
||||||
handleClose={() => setDeleteIssueModal(false)}
|
handleClose={() => setDeleteIssueModal(false)}
|
||||||
data={issue ? { ...issue } : null}
|
data={issue ? { ...issue } : null}
|
||||||
onSubmit={handleDeleteIssue}
|
onSubmit={handleDeleteIssue}
|
||||||
user={user}
|
user={user}
|
||||||
/>
|
/>
|
||||||
<Transition.Root appear show={isSidePeekOpen} as={React.Fragment}>
|
<Transition.Root appear show={isSidePeekOpen} as={React.Fragment}>
|
||||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||||
<div className="fixed inset-0 z-20 h-full w-full overflow-y-auto">
|
<div className="fixed inset-0 z-20 h-full w-full overflow-y-auto">
|
||||||
<Transition.Child
|
<Transition.Child
|
||||||
as={React.Fragment}
|
as={React.Fragment}
|
||||||
enter="transition-transform duration-300"
|
enter="transition-transform duration-300"
|
||||||
enterFrom="translate-x-full"
|
enterFrom="translate-x-full"
|
||||||
enterTo="translate-x-0"
|
enterTo="translate-x-0"
|
||||||
leave="transition-transform duration-200"
|
leave="transition-transform duration-200"
|
||||||
leaveFrom="translate-x-0"
|
leaveFrom="translate-x-0"
|
||||||
leaveTo="translate-x-full"
|
leaveTo="translate-x-full"
|
||||||
>
|
>
|
||||||
<Dialog.Panel className="fixed z-20 bg-custom-background-100 top-0 right-0 h-full w-1/2 shadow-custom-shadow-md">
|
<Dialog.Panel className="fixed z-20 bg-custom-background-100 top-0 right-0 h-full w-1/2 shadow-custom-shadow-md">
|
||||||
<SidePeekView
|
<SidePeekView
|
||||||
handleClose={handleClose}
|
handleClose={handleClose}
|
||||||
handleDeleteIssue={() => setDeleteIssueModal(true)}
|
handleDeleteIssue={() => setDeleteIssueModal(true)}
|
||||||
handleUpdateIssue={handleUpdateIssue}
|
handleUpdateIssue={handleUpdateIssue}
|
||||||
issue={issue}
|
issue={issue}
|
||||||
mode={peekOverviewMode}
|
mode={peekOverviewMode}
|
||||||
readOnly={readOnly}
|
readOnly={readOnly}
|
||||||
setMode={(mode) => setPeekOverviewMode(mode)}
|
setMode={(mode) => setPeekOverviewMode(mode)}
|
||||||
workspaceSlug={workspaceSlug}
|
workspaceSlug={workspaceSlug}
|
||||||
/>
|
/>
|
||||||
</Dialog.Panel>
|
</Dialog.Panel>
|
||||||
</Transition.Child>
|
</Transition.Child>
|
||||||
</div>
|
</div>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</Transition.Root>
|
</Transition.Root>
|
||||||
<Transition.Root appear show={isModalPeekOpen} as={React.Fragment}>
|
<Transition.Root appear show={isModalPeekOpen} as={React.Fragment}>
|
||||||
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
<Dialog as="div" className="relative z-20" onClose={handleClose}>
|
||||||
|
<Transition.Child
|
||||||
|
as={React.Fragment}
|
||||||
|
enter="ease-out duration-300"
|
||||||
|
enterFrom="opacity-0"
|
||||||
|
enterTo="opacity-100"
|
||||||
|
leave="ease-in duration-200"
|
||||||
|
leaveFrom="opacity-100"
|
||||||
|
leaveTo="opacity-0"
|
||||||
|
>
|
||||||
|
<div className="fixed inset-0 bg-custom-backdrop bg-opacity-50 transition-opacity" />
|
||||||
|
</Transition.Child>
|
||||||
|
<div className="fixed inset-0 z-20 h-full w-full overflow-y-auto">
|
||||||
<Transition.Child
|
<Transition.Child
|
||||||
as={React.Fragment}
|
as={React.Fragment}
|
||||||
enter="ease-out duration-300"
|
enter="ease-out duration-300"
|
||||||
@ -139,55 +150,42 @@ export const IssuePeekOverview: React.FC<Props> = observer(
|
|||||||
leaveFrom="opacity-100"
|
leaveFrom="opacity-100"
|
||||||
leaveTo="opacity-0"
|
leaveTo="opacity-0"
|
||||||
>
|
>
|
||||||
<div className="fixed inset-0 bg-custom-backdrop bg-opacity-50 transition-opacity" />
|
<Dialog.Panel>
|
||||||
|
<div
|
||||||
|
className={`fixed z-20 bg-custom-background-100 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-lg shadow-custom-shadow-xl transition-all duration-300 ${
|
||||||
|
peekOverviewMode === "modal" ? "h-[70%] w-3/5" : "h-[95%] w-[95%]"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{peekOverviewMode === "modal" && (
|
||||||
|
<SidePeekView
|
||||||
|
handleClose={handleClose}
|
||||||
|
handleDeleteIssue={() => setDeleteIssueModal(true)}
|
||||||
|
handleUpdateIssue={handleUpdateIssue}
|
||||||
|
issue={issue}
|
||||||
|
mode={peekOverviewMode}
|
||||||
|
readOnly={readOnly}
|
||||||
|
setMode={(mode) => setPeekOverviewMode(mode)}
|
||||||
|
workspaceSlug={workspaceSlug}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{peekOverviewMode === "full" && (
|
||||||
|
<FullScreenPeekView
|
||||||
|
handleClose={handleClose}
|
||||||
|
handleDeleteIssue={() => setDeleteIssueModal(true)}
|
||||||
|
handleUpdateIssue={handleUpdateIssue}
|
||||||
|
issue={issue}
|
||||||
|
mode={peekOverviewMode}
|
||||||
|
readOnly={readOnly}
|
||||||
|
setMode={(mode) => setPeekOverviewMode(mode)}
|
||||||
|
workspaceSlug={workspaceSlug}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Dialog.Panel>
|
||||||
</Transition.Child>
|
</Transition.Child>
|
||||||
<div className="fixed inset-0 z-20 h-full w-full overflow-y-auto">
|
</div>
|
||||||
<Transition.Child
|
</Dialog>
|
||||||
as={React.Fragment}
|
</Transition.Root>
|
||||||
enter="ease-out duration-300"
|
</>
|
||||||
enterFrom="opacity-0"
|
);
|
||||||
enterTo="opacity-100"
|
});
|
||||||
leave="ease-in duration-200"
|
|
||||||
leaveFrom="opacity-100"
|
|
||||||
leaveTo="opacity-0"
|
|
||||||
>
|
|
||||||
<Dialog.Panel>
|
|
||||||
<div
|
|
||||||
className={`fixed z-20 bg-custom-background-100 top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 rounded-lg shadow-custom-shadow-xl transition-all duration-300 ${
|
|
||||||
peekOverviewMode === "modal" ? "h-[70%] w-3/5" : "h-[95%] w-[95%]"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
{peekOverviewMode === "modal" && (
|
|
||||||
<SidePeekView
|
|
||||||
handleClose={handleClose}
|
|
||||||
handleDeleteIssue={() => setDeleteIssueModal(true)}
|
|
||||||
handleUpdateIssue={handleUpdateIssue}
|
|
||||||
issue={issue}
|
|
||||||
mode={peekOverviewMode}
|
|
||||||
readOnly={readOnly}
|
|
||||||
setMode={(mode) => setPeekOverviewMode(mode)}
|
|
||||||
workspaceSlug={workspaceSlug}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{peekOverviewMode === "full" && (
|
|
||||||
<FullScreenPeekView
|
|
||||||
handleClose={handleClose}
|
|
||||||
handleDeleteIssue={() => setDeleteIssueModal(true)}
|
|
||||||
handleUpdateIssue={handleUpdateIssue}
|
|
||||||
issue={issue}
|
|
||||||
mode={peekOverviewMode}
|
|
||||||
readOnly={readOnly}
|
|
||||||
setMode={(mode) => setPeekOverviewMode(mode)}
|
|
||||||
workspaceSlug={workspaceSlug}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Dialog.Panel>
|
|
||||||
</Transition.Child>
|
|
||||||
</div>
|
|
||||||
</Dialog>
|
|
||||||
</Transition.Root>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
@ -3,57 +3,43 @@ import { observable, action, makeObservable, runInAction } from "mobx";
|
|||||||
import { RootStore } from "./root";
|
import { RootStore } from "./root";
|
||||||
// services
|
// services
|
||||||
import { IssueService } from "services/issue.service";
|
import { IssueService } from "services/issue.service";
|
||||||
|
import { IIssue } from "types";
|
||||||
|
|
||||||
export type IPeekMode = "side" | "modal" | "full";
|
export type IPeekMode = "side" | "modal" | "full";
|
||||||
|
|
||||||
export interface IIssueViewDetailStore {
|
export interface IIssueDetailStore {
|
||||||
loader: boolean;
|
loader: boolean;
|
||||||
error: any | null;
|
error: any | null;
|
||||||
|
|
||||||
peekId: string | null;
|
peekId: string | null;
|
||||||
peekMode: IPeekMode | null;
|
peekMode: IPeekMode | null;
|
||||||
|
|
||||||
issue_detail: {
|
issues: {
|
||||||
workspace: {
|
[key: string]: IIssue;
|
||||||
[key: string]: {
|
|
||||||
issues: {
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
setPeekId: (issueId: string | null) => void;
|
setPeekId: (issueId: string | null) => void;
|
||||||
setPeekMode: (issueId: IPeekMode | null) => void;
|
setPeekMode: (issueId: IPeekMode | null) => void;
|
||||||
|
|
||||||
// fetch issue details
|
// fetch issue details
|
||||||
fetchIssueDetailsAsync: (workspaceId: string, projectId: string, issueId: string) => void;
|
fetchIssueDetails: (workspaceId: string, projectId: string, issueId: string) => void;
|
||||||
// creating issue
|
// creating issue
|
||||||
createIssueAsync: (workspaceId: string, projectId: string, issueId: string, data: any) => void;
|
createIssue: (workspaceId: string, projectId: string, issueId: string, data: any) => void;
|
||||||
// updating issue
|
// updating issue
|
||||||
updateIssueAsync: (workspaceId: string, projectId: string, issueId: string, data: any) => void;
|
updateIssue: (workspaceId: string, projectId: string, issueId: string, data: any) => void;
|
||||||
// deleting issue
|
// deleting issue
|
||||||
deleteIssueAsync: (workspaceId: string, projectId: string, issueId: string) => void;
|
deleteIssue: (workspaceId: string, projectId: string, issueId: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
class IssueViewDetailStore implements IIssueViewDetailStore {
|
class IssueDetailStore implements IIssueDetailStore {
|
||||||
loader: boolean = false;
|
loader: boolean = false;
|
||||||
error: any | null = null;
|
error: any | null = null;
|
||||||
|
|
||||||
peekId: string | null = null;
|
peekId: string | null = null;
|
||||||
peekMode: IPeekMode | null = null;
|
peekMode: IPeekMode | null = null;
|
||||||
|
|
||||||
issue_detail: {
|
issues: {
|
||||||
workspace: {
|
[key: string]: IIssue;
|
||||||
[key: string]: {
|
} = {};
|
||||||
issues: {
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
} = {
|
|
||||||
workspace: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
// root store
|
// root store
|
||||||
rootStore;
|
rootStore;
|
||||||
@ -63,20 +49,21 @@ class IssueViewDetailStore implements IIssueViewDetailStore {
|
|||||||
constructor(_rootStore: RootStore) {
|
constructor(_rootStore: RootStore) {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
// observable
|
// observable
|
||||||
loader: observable,
|
loader: observable.ref,
|
||||||
error: observable,
|
error: observable.ref,
|
||||||
|
|
||||||
peekId: observable,
|
peekId: observable.ref,
|
||||||
peekMode: observable,
|
peekMode: observable.ref,
|
||||||
issue_detail: observable,
|
|
||||||
|
issues: observable.ref,
|
||||||
|
|
||||||
setPeekId: action,
|
setPeekId: action,
|
||||||
setPeekMode: action,
|
setPeekMode: action,
|
||||||
|
|
||||||
fetchIssueDetailsAsync: action,
|
fetchIssueDetails: action,
|
||||||
createIssueAsync: action,
|
createIssue: action,
|
||||||
updateIssueAsync: action,
|
updateIssue: action,
|
||||||
deleteIssueAsync: action,
|
deleteIssue: action,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.rootStore = _rootStore;
|
this.rootStore = _rootStore;
|
||||||
@ -84,20 +71,22 @@ class IssueViewDetailStore implements IIssueViewDetailStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setPeekId = (issueId: string | null) => (this.peekId = issueId);
|
setPeekId = (issueId: string | null) => (this.peekId = issueId);
|
||||||
|
|
||||||
setPeekMode = (mode: IPeekMode | null) => (this.peekMode = mode);
|
setPeekMode = (mode: IPeekMode | null) => (this.peekMode = mode);
|
||||||
|
|
||||||
fetchIssueDetailsAsync = async (workspaceId: string, projectId: string, issueId: string) => {
|
fetchIssueDetails = async (workspaceId: string, projectId: string, issueId: string) => {
|
||||||
try {
|
try {
|
||||||
this.loader = true;
|
this.loader = true;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
console.log("workspaceId", workspaceId);
|
const issueDetailsResponse = await this.issueService.retrieve(workspaceId, projectId, issueId);
|
||||||
console.log("projectId", projectId);
|
|
||||||
console.log("issueId", issueId);
|
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
this.loader = false;
|
this.loader = false;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
|
this.issues = {
|
||||||
|
[issueId]: issueDetailsResponse,
|
||||||
|
};
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("error in fetching issue details", error);
|
console.log("error in fetching issue details", error);
|
||||||
@ -107,7 +96,7 @@ class IssueViewDetailStore implements IIssueViewDetailStore {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
createIssueAsync = async (workspaceId: string, projectId: string, issueId: string, data: any) => {
|
createIssue = async (workspaceId: string, projectId: string, issueId: string, data: any) => {
|
||||||
try {
|
try {
|
||||||
this.loader = true;
|
this.loader = true;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
@ -129,12 +118,12 @@ class IssueViewDetailStore implements IIssueViewDetailStore {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
updateIssueAsync = async (workspaceId: string, projectId: string, issueId: string, data: any) => {
|
updateIssue = async (workspaceId: string, projectId: string, issueId: string, data: any) => {
|
||||||
try {
|
try {
|
||||||
this.loader = true;
|
this.loader = true;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
const filteredParams = this.rootStore.issueFilters.getComputedFilters(
|
const filteredParams = this.rootStore.issueFilter.getComputedFilters(
|
||||||
workspaceId,
|
workspaceId,
|
||||||
projectId,
|
projectId,
|
||||||
null,
|
null,
|
||||||
@ -161,7 +150,7 @@ class IssueViewDetailStore implements IIssueViewDetailStore {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
deleteIssueAsync = async (workspaceId: string, projectId: string, issueId: string) => {
|
deleteIssue = async (workspaceId: string, projectId: string, issueId: string) => {
|
||||||
try {
|
try {
|
||||||
this.loader = true;
|
this.loader = true;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
@ -183,4 +172,4 @@ class IssueViewDetailStore implements IIssueViewDetailStore {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default IssueViewDetailStore;
|
export default IssueDetailStore;
|
||||||
|
Loading…
Reference in New Issue
Block a user