mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: issue link mobx integration (#3072)
* chore: issue link mobx integration * chore: issue link code refactor and build fix
This commit is contained in:
parent
f119d702c7
commit
c33cfeb227
@ -14,8 +14,8 @@ type Props = {
|
||||
handleClose: () => void;
|
||||
data?: ILinkDetails | null;
|
||||
status: boolean;
|
||||
createIssueLink: (formData: IIssueLink | ModuleLink) => Promise<void>;
|
||||
updateIssueLink: (formData: IIssueLink | ModuleLink, linkId: string) => Promise<void>;
|
||||
createIssueLink: (formData: IIssueLink | ModuleLink) => Promise<ILinkDetails> | Promise<void> | void;
|
||||
updateIssueLink: (formData: IIssueLink | ModuleLink, linkId: string) => Promise<ILinkDetails> | Promise<void> | void;
|
||||
};
|
||||
|
||||
const defaultValues: IIssueLink | ModuleLink = {
|
||||
@ -31,7 +31,7 @@ export const LinkModal: FC<Props> = (props) => {
|
||||
handleSubmit,
|
||||
control,
|
||||
reset,
|
||||
} = useForm<ModuleLink>({
|
||||
} = useForm<IIssueLink | ModuleLink>({
|
||||
defaultValues,
|
||||
});
|
||||
|
||||
@ -158,8 +158,8 @@ export const LinkModal: FC<Props> = (props) => {
|
||||
? "Updating Link..."
|
||||
: "Update Link"
|
||||
: isSubmitting
|
||||
? "Adding Link..."
|
||||
: "Add Link"}
|
||||
? "Adding Link..."
|
||||
: "Add Link"}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { FC, useState } from "react";
|
||||
import { mutate } from "swr";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
import { observer } from "mobx-react-lite";
|
||||
// mobx store
|
||||
@ -17,30 +17,25 @@ import {
|
||||
SidebarPrioritySelect,
|
||||
SidebarStateSelect,
|
||||
} from "../sidebar-select";
|
||||
// services
|
||||
import { IssueService } from "services/issue";
|
||||
// hooks
|
||||
import useToast from "hooks/use-toast";
|
||||
// components
|
||||
import { CustomDatePicker } from "components/ui";
|
||||
import { LinkModal, LinksList } from "components/core";
|
||||
// types
|
||||
import { IIssue, IIssueLink, TIssuePriorities, ILinkDetails } from "types";
|
||||
// fetch-keys
|
||||
import { ISSUE_DETAILS } from "constants/fetch-keys";
|
||||
import { IIssue, TIssuePriorities, ILinkDetails, IIssueLink } from "types";
|
||||
// constants
|
||||
import { EUserWorkspaceRoles } from "constants/workspace";
|
||||
|
||||
interface IPeekOverviewProperties {
|
||||
issue: IIssue;
|
||||
issueUpdate: (issue: Partial<IIssue>) => void;
|
||||
issueLinkCreate: (data: IIssueLink) => Promise<ILinkDetails>;
|
||||
issueLinkUpdate: (data: IIssueLink, linkId: string) => Promise<ILinkDetails>;
|
||||
issueLinkDelete: (linkId: string) => Promise<void>;
|
||||
disableUserActions: boolean;
|
||||
}
|
||||
|
||||
const issueService = new IssueService();
|
||||
|
||||
export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((props) => {
|
||||
const { issue, issueUpdate, disableUserActions } = props;
|
||||
const { issue, issueUpdate, issueLinkCreate, issueLinkUpdate, issueLinkDelete, disableUserActions } = props;
|
||||
// states
|
||||
const [linkModal, setLinkModal] = useState(false);
|
||||
const [selectedLinkToUpdate, setSelectedLinkToUpdate] = useState<ILinkDetails | null>(null);
|
||||
@ -54,8 +49,6 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId } = router.query;
|
||||
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
const handleState = (_state: string) => {
|
||||
issueUpdate({ ...issue, state: _state });
|
||||
};
|
||||
@ -81,61 +74,6 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
|
||||
issueUpdate({ ...issue, ...formData });
|
||||
};
|
||||
|
||||
const handleCreateLink = async (formData: IIssueLink) => {
|
||||
if (!workspaceSlug || !projectId || !issue) return;
|
||||
|
||||
const payload = { metadata: {}, ...formData };
|
||||
|
||||
await issueService
|
||||
.createIssueLink(workspaceSlug as string, projectId as string, issue.id, payload)
|
||||
.then(() => mutate(ISSUE_DETAILS(issue.id)))
|
||||
.catch((err) => {
|
||||
if (err.status === 400)
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "This URL already exists for this issue.",
|
||||
});
|
||||
else
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "Something went wrong. Please try again.",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const handleUpdateLink = async (formData: IIssueLink, linkId: string) => {
|
||||
if (!workspaceSlug || !projectId || !issue) return;
|
||||
|
||||
const payload = { metadata: {}, ...formData };
|
||||
|
||||
const updatedLinks = issue.issue_link.map((l) =>
|
||||
l.id === linkId
|
||||
? {
|
||||
...l,
|
||||
title: formData.title,
|
||||
url: formData.url,
|
||||
}
|
||||
: l
|
||||
);
|
||||
|
||||
mutate<IIssue>(
|
||||
ISSUE_DETAILS(issue.id),
|
||||
(prevData) => ({ ...(prevData as IIssue), issue_link: updatedLinks }),
|
||||
false
|
||||
);
|
||||
|
||||
await issueService
|
||||
.updateIssueLink(workspaceSlug as string, projectId as string, issue.id, linkId, payload)
|
||||
.then(() => {
|
||||
mutate(ISSUE_DETAILS(issue.id));
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
const handleCycleOrModuleChange = async () => {
|
||||
if (!workspaceSlug || !projectId) return;
|
||||
|
||||
@ -147,27 +85,6 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
|
||||
setLinkModal(true);
|
||||
};
|
||||
|
||||
const handleDeleteLink = async (linkId: string) => {
|
||||
if (!workspaceSlug || !projectId || !issue) return;
|
||||
|
||||
const updatedLinks = issue.issue_link.filter((l) => l.id !== linkId);
|
||||
|
||||
mutate<IIssue>(
|
||||
ISSUE_DETAILS(issue.id),
|
||||
(prevData) => ({ ...(prevData as IIssue), issue_link: updatedLinks }),
|
||||
false
|
||||
);
|
||||
|
||||
await issueService
|
||||
.deleteIssueLink(workspaceSlug as string, projectId as string, issue.id, linkId)
|
||||
.then(() => {
|
||||
mutate(ISSUE_DETAILS(issue.id));
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
const projectDetails = workspaceSlug ? getProjectById(workspaceSlug.toString(), issue.project) : null;
|
||||
const isEstimateEnabled = projectDetails?.estimate;
|
||||
|
||||
@ -187,8 +104,8 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
|
||||
}}
|
||||
data={selectedLinkToUpdate}
|
||||
status={selectedLinkToUpdate ? true : false}
|
||||
createIssueLink={handleCreateLink}
|
||||
updateIssueLink={handleUpdateLink}
|
||||
createIssueLink={issueLinkCreate}
|
||||
updateIssueLink={issueLinkUpdate}
|
||||
/>
|
||||
<div className="flex flex-col">
|
||||
<div className="flex w-full flex-col gap-5 py-5">
|
||||
@ -373,7 +290,7 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
|
||||
{issue?.issue_link && issue.issue_link.length > 0 ? (
|
||||
<LinksList
|
||||
links={issue.issue_link}
|
||||
handleDeleteLink={handleDeleteLink}
|
||||
handleDeleteLink={issueLinkDelete}
|
||||
handleEditLink={handleEditLink}
|
||||
userAuth={{
|
||||
isGuest: currentProjectRole === EUserWorkspaceRoles.GUEST,
|
||||
|
@ -10,7 +10,7 @@ import { IssueView } from "components/issues";
|
||||
// helpers
|
||||
import { copyUrlToClipboard } from "helpers/string.helper";
|
||||
// types
|
||||
import { IIssue } from "types";
|
||||
import { IIssue, IIssueLink } from "types";
|
||||
// constants
|
||||
import { EUserWorkspaceRoles } from "constants/workspace";
|
||||
|
||||
@ -42,6 +42,9 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
|
||||
removeIssueReaction,
|
||||
createIssueSubscription,
|
||||
removeIssueSubscription,
|
||||
createIssueLink,
|
||||
updateIssueLink,
|
||||
deleteIssueLink,
|
||||
getIssue,
|
||||
loader,
|
||||
fetchPeekIssueDetails,
|
||||
@ -121,6 +124,13 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
|
||||
|
||||
const issueSubscriptionRemove = () => removeIssueSubscription(workspaceSlug, projectId, issueId);
|
||||
|
||||
const issueLinkCreate = (formData: IIssueLink) => createIssueLink(workspaceSlug, projectId, issueId, formData);
|
||||
|
||||
const issueLinkUpdate = (formData: IIssueLink, linkId: string) =>
|
||||
updateIssueLink(workspaceSlug, projectId, issueId, linkId, formData);
|
||||
|
||||
const issueLinkDelete = (linkId: string) => deleteIssueLink(workspaceSlug, projectId, issueId, linkId);
|
||||
|
||||
const handleDeleteIssue = async () => {
|
||||
if (isArchived) await deleteArchivedIssue(workspaceSlug, projectId, issue!);
|
||||
else removeIssueFromStructure(workspaceSlug, projectId, issue!);
|
||||
@ -159,6 +169,9 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
|
||||
issueCommentReactionRemove={issueCommentReactionRemove}
|
||||
issueSubscriptionCreate={issueSubscriptionCreate}
|
||||
issueSubscriptionRemove={issueSubscriptionRemove}
|
||||
issueLinkCreate={issueLinkCreate}
|
||||
issueLinkUpdate={issueLinkUpdate}
|
||||
issueLinkDelete={issueLinkDelete}
|
||||
handleDeleteIssue={handleDeleteIssue}
|
||||
disableUserActions={[5, 10].includes(userRole)}
|
||||
showCommentAccessSpecifier={currentProjectDetails?.is_deployed}
|
||||
|
@ -17,7 +17,7 @@ import {
|
||||
// ui
|
||||
import { Button, CenterPanelIcon, CustomSelect, FullScreenPanelIcon, SidePanelIcon, Spinner } from "@plane/ui";
|
||||
// types
|
||||
import { IIssue } from "types";
|
||||
import { IIssue, IIssueLink, ILinkDetails } from "types";
|
||||
|
||||
interface IIssueView {
|
||||
workspaceSlug: string;
|
||||
@ -38,6 +38,9 @@ interface IIssueView {
|
||||
issueCommentReactionRemove: (commentId: string, reaction: string) => void;
|
||||
issueSubscriptionCreate: () => void;
|
||||
issueSubscriptionRemove: () => void;
|
||||
issueLinkCreate: (formData: IIssueLink) => Promise<ILinkDetails>;
|
||||
issueLinkUpdate: (formData: IIssueLink, linkId: string) => Promise<ILinkDetails>;
|
||||
issueLinkDelete: (linkId: string) => Promise<void>;
|
||||
handleDeleteIssue: () => Promise<void>;
|
||||
children: ReactNode;
|
||||
disableUserActions?: boolean;
|
||||
@ -84,6 +87,9 @@ export const IssueView: FC<IIssueView> = observer((props) => {
|
||||
issueCommentReactionRemove,
|
||||
issueSubscriptionCreate,
|
||||
issueSubscriptionRemove,
|
||||
issueLinkCreate,
|
||||
issueLinkUpdate,
|
||||
issueLinkDelete,
|
||||
handleDeleteIssue,
|
||||
children,
|
||||
disableUserActions = false,
|
||||
@ -286,6 +292,9 @@ export const IssueView: FC<IIssueView> = observer((props) => {
|
||||
<PeekOverviewProperties
|
||||
issue={issue}
|
||||
issueUpdate={issueUpdate}
|
||||
issueLinkCreate={issueLinkCreate}
|
||||
issueLinkUpdate={issueLinkUpdate}
|
||||
issueLinkDelete={issueLinkDelete}
|
||||
disableUserActions={disableUserActions}
|
||||
/>
|
||||
|
||||
@ -342,6 +351,9 @@ export const IssueView: FC<IIssueView> = observer((props) => {
|
||||
<PeekOverviewProperties
|
||||
issue={issue}
|
||||
issueUpdate={issueUpdate}
|
||||
issueLinkCreate={issueLinkCreate}
|
||||
issueLinkUpdate={issueLinkUpdate}
|
||||
issueLinkDelete={issueLinkDelete}
|
||||
disableUserActions={disableUserActions}
|
||||
/>
|
||||
</div>
|
||||
|
@ -84,6 +84,7 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
|
||||
user: { currentUser, currentProjectRole },
|
||||
projectState: { states },
|
||||
projectIssues: { removeIssue },
|
||||
issueDetail: { createIssueLink, updateIssueLink, deleteIssueLink },
|
||||
} = useMobxStore();
|
||||
|
||||
const router = useRouter();
|
||||
@ -129,80 +130,19 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
|
||||
[workspaceSlug, projectId, issueId, issueDetail, currentUser]
|
||||
);
|
||||
|
||||
const handleCreateLink = async (formData: IIssueLink) => {
|
||||
if (!workspaceSlug || !projectId || !issueDetail) return;
|
||||
|
||||
const payload = { metadata: {}, ...formData };
|
||||
|
||||
await issueService
|
||||
.createIssueLink(workspaceSlug as string, projectId as string, issueDetail.id, payload)
|
||||
.then(() => mutate(ISSUE_DETAILS(issueDetail.id)))
|
||||
.catch((err) => {
|
||||
if (err.status === 400)
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "This URL already exists for this issue.",
|
||||
});
|
||||
else
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "Something went wrong. Please try again.",
|
||||
});
|
||||
});
|
||||
const issueLinkCreate = (formData: IIssueLink) => {
|
||||
if (!workspaceSlug || !projectId || !issueId) return;
|
||||
createIssueLink(workspaceSlug.toString(), projectId.toString(), issueId.toString(), formData);
|
||||
};
|
||||
|
||||
const handleUpdateLink = async (formData: IIssueLink, linkId: string) => {
|
||||
if (!workspaceSlug || !projectId || !issueDetail) return;
|
||||
|
||||
const payload = { metadata: {}, ...formData };
|
||||
|
||||
const updatedLinks = issueDetail.issue_link.map((l) =>
|
||||
l.id === linkId
|
||||
? {
|
||||
...l,
|
||||
title: formData.title,
|
||||
url: formData.url,
|
||||
}
|
||||
: l
|
||||
);
|
||||
|
||||
mutate<IIssue>(
|
||||
ISSUE_DETAILS(issueDetail.id),
|
||||
(prevData) => ({ ...(prevData as IIssue), issue_link: updatedLinks }),
|
||||
false
|
||||
);
|
||||
|
||||
await issueService
|
||||
.updateIssueLink(workspaceSlug as string, projectId as string, issueDetail.id, linkId, payload)
|
||||
.then(() => {
|
||||
mutate(ISSUE_DETAILS(issueDetail.id));
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
const issueLinkUpdate = (formData: IIssueLink, linkId: string) => {
|
||||
if (!workspaceSlug || !projectId || !issueId) return;
|
||||
updateIssueLink(workspaceSlug.toString(), projectId.toString(), issueId.toString(), linkId, formData);
|
||||
};
|
||||
|
||||
const handleDeleteLink = async (linkId: string) => {
|
||||
if (!workspaceSlug || !projectId || !issueDetail) return;
|
||||
|
||||
const updatedLinks = issueDetail.issue_link.filter((l) => l.id !== linkId);
|
||||
|
||||
mutate<IIssue>(
|
||||
ISSUE_DETAILS(issueDetail.id),
|
||||
(prevData) => ({ ...(prevData as IIssue), issue_link: updatedLinks }),
|
||||
false
|
||||
);
|
||||
|
||||
await issueService
|
||||
.deleteIssueLink(workspaceSlug as string, projectId as string, issueDetail.id, linkId)
|
||||
.then(() => {
|
||||
mutate(ISSUE_DETAILS(issueDetail.id));
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
const issueLinkDelete = (linkId: string) => {
|
||||
if (!workspaceSlug || !projectId || !issueId) return;
|
||||
deleteIssueLink(workspaceSlug.toString(), projectId.toString(), issueId.toString(), linkId);
|
||||
};
|
||||
|
||||
const handleCopyText = () => {
|
||||
@ -264,8 +204,8 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
|
||||
}}
|
||||
data={selectedLinkToUpdate}
|
||||
status={selectedLinkToUpdate ? true : false}
|
||||
createIssueLink={handleCreateLink}
|
||||
updateIssueLink={handleUpdateLink}
|
||||
createIssueLink={issueLinkCreate}
|
||||
updateIssueLink={issueLinkUpdate}
|
||||
/>
|
||||
{workspaceSlug && projectId && issueDetail && (
|
||||
<DeleteIssueModal
|
||||
@ -659,7 +599,7 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
|
||||
{
|
||||
<LinksList
|
||||
links={issueDetail.issue_link}
|
||||
handleDeleteLink={handleDeleteLink}
|
||||
handleDeleteLink={issueLinkDelete}
|
||||
handleEditLink={handleEditLink}
|
||||
userAuth={{
|
||||
isGuest: currentProjectRole === 5,
|
||||
|
@ -1,7 +1,7 @@
|
||||
// services
|
||||
import { APIService } from "services/api.service";
|
||||
// type
|
||||
import type { IUser, IIssue, IIssueActivity, ISubIssueResponse, IIssueDisplayProperties } from "types";
|
||||
import type { IIssue, IIssueActivity, ISubIssueResponse, IIssueDisplayProperties, ILinkDetails, IIssueLink } from "types";
|
||||
import { IIssueResponse } from "store/issues/types";
|
||||
// helper
|
||||
import { API_BASE_URL } from "helpers/common.helper";
|
||||
@ -184,12 +184,8 @@ export class IssueService extends APIService {
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
data: {
|
||||
metadata: any;
|
||||
title: string;
|
||||
url: string;
|
||||
}
|
||||
): Promise<any> {
|
||||
data: IIssueLink
|
||||
): Promise<ILinkDetails> {
|
||||
return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-links/`, data)
|
||||
.then((response) => response?.data)
|
||||
.catch((error) => {
|
||||
@ -202,12 +198,8 @@ export class IssueService extends APIService {
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
linkId: string,
|
||||
data: {
|
||||
metadata: any;
|
||||
title: string;
|
||||
url: string;
|
||||
}
|
||||
): Promise<any> {
|
||||
data: IIssueLink
|
||||
): Promise<ILinkDetails> {
|
||||
return this.patch(
|
||||
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-links/${linkId}/`,
|
||||
data
|
||||
|
@ -1,7 +1,7 @@
|
||||
// services
|
||||
import { APIService } from "services/api.service";
|
||||
// types
|
||||
import type { IModule, IIssue, ILinkDetails } from "types";
|
||||
import type { IModule, IIssue, ILinkDetails, ModuleLink } from "types";
|
||||
import { IIssueResponse } from "store/issues/types";
|
||||
import { API_BASE_URL } from "helpers/common.helper";
|
||||
|
||||
@ -132,7 +132,7 @@ export class ModuleService extends APIService {
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
moduleId: string,
|
||||
data: Partial<ILinkDetails>
|
||||
data: ModuleLink
|
||||
): Promise<ILinkDetails> {
|
||||
return this.post(`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/module-links/`, data)
|
||||
.then((response) => response?.data)
|
||||
@ -146,7 +146,7 @@ export class ModuleService extends APIService {
|
||||
projectId: string,
|
||||
moduleId: string,
|
||||
linkId: string,
|
||||
data: Partial<ILinkDetails>
|
||||
data: ModuleLink
|
||||
): Promise<ILinkDetails> {
|
||||
return this.patch(
|
||||
`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/module-links/${linkId}/`,
|
||||
|
@ -4,7 +4,7 @@ import { IssueService, IssueReactionService, IssueCommentService } from "service
|
||||
import { NotificationService } from "services/notification.service";
|
||||
// types
|
||||
import { RootStore } from "../root";
|
||||
import type { IIssue, IIssueActivity } from "types";
|
||||
import type { IIssue, IIssueActivity, IIssueLink, ILinkDetails } from "types";
|
||||
// constants
|
||||
import { groupReactionEmojis } from "constants/issue";
|
||||
|
||||
@ -51,6 +51,21 @@ export interface IIssueDetailStore {
|
||||
createIssueReaction: (workspaceSlug: string, projectId: string, issueId: string, reaction: string) => Promise<void>;
|
||||
removeIssueReaction: (workspaceSlug: string, projectId: string, issueId: string, reaction: string) => Promise<void>;
|
||||
|
||||
createIssueLink: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
data: IIssueLink
|
||||
) => Promise<ILinkDetails>;
|
||||
updateIssueLink: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
linkId: string,
|
||||
data: IIssueLink
|
||||
) => Promise<ILinkDetails>;
|
||||
deleteIssueLink: (workspaceSlug: string, projectId: string, issueId: string, linkId: string) => Promise<void>;
|
||||
|
||||
fetchIssueActivity: (workspaceSlug: string, projectId: string, issueId: string) => Promise<void>;
|
||||
createIssueComment: (workspaceSlug: string, projectId: string, issueId: string, data: any) => Promise<void>;
|
||||
updateIssueComment: (
|
||||
@ -147,6 +162,10 @@ export class IssueDetailStore implements IIssueDetailStore {
|
||||
createIssueReaction: action,
|
||||
removeIssueReaction: action,
|
||||
|
||||
createIssueLink: action,
|
||||
updateIssueLink: action,
|
||||
deleteIssueLink: action,
|
||||
|
||||
fetchIssueActivity: action,
|
||||
createIssueComment: action,
|
||||
updateIssueComment: action,
|
||||
@ -590,6 +609,91 @@ export class IssueDetailStore implements IIssueDetailStore {
|
||||
}
|
||||
};
|
||||
|
||||
createIssueLink = async (workspaceSlug: string, projectId: string, issueId: string, data: IIssueLink) => {
|
||||
try {
|
||||
const response = await this.issueService.createIssueLink(workspaceSlug, projectId, issueId, data);
|
||||
|
||||
runInAction(() => {
|
||||
this.issues = {
|
||||
...this.issues,
|
||||
[issueId]: {
|
||||
...this.issues[issueId],
|
||||
issue_link: [response, ...this.issues[issueId].issue_link],
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error("Failed to create link in store", error);
|
||||
|
||||
this.fetchIssueDetails(workspaceSlug, projectId, issueId);
|
||||
|
||||
runInAction(() => {
|
||||
this.error = error;
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
updateIssueLink = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
linkId: string,
|
||||
data: IIssueLink
|
||||
) => {
|
||||
try {
|
||||
const response = await this.issueService.updateIssueLink(workspaceSlug, projectId, issueId, linkId, data);
|
||||
|
||||
runInAction(() => {
|
||||
this.issues = {
|
||||
...this.issues,
|
||||
[issueId]: {
|
||||
...this.issues[issueId],
|
||||
issue_link: this.issues[issueId].issue_link.map((link) => (link.id === linkId ? response : link)),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error("Failed to update link in issue store", error);
|
||||
|
||||
this.fetchIssueDetails(workspaceSlug, projectId, issueId);
|
||||
|
||||
runInAction(() => {
|
||||
this.error = error;
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
deleteIssueLink = async (workspaceSlug: string, projectId: string, issueId: string, linkId: string) => {
|
||||
try {
|
||||
runInAction(() => {
|
||||
this.issues = {
|
||||
...this.issues,
|
||||
[issueId]: {
|
||||
...this.issues[issueId],
|
||||
issue_link: this.issues[issueId].issue_link.filter((link) => link.id !== linkId),
|
||||
},
|
||||
};
|
||||
});
|
||||
await this.issueService.deleteIssueLink(workspaceSlug, projectId, issueId, linkId);
|
||||
} catch (error) {
|
||||
console.error("Failed to delete link in issue store", error);
|
||||
|
||||
runInAction(() => {
|
||||
this.error = error;
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// subscriptions
|
||||
fetchIssueSubscription = async (workspaceSlug: string, projectId: string, issueId: string) => {
|
||||
try {
|
||||
|
@ -4,7 +4,7 @@ import { ProjectService } from "services/project";
|
||||
import { ModuleService } from "services/module.service";
|
||||
// types
|
||||
import { RootStore } from "../root";
|
||||
import { IIssue, IModule, ILinkDetails } from "types";
|
||||
import { IIssue, IModule, ILinkDetails, ModuleLink } from "types";
|
||||
import {
|
||||
IIssueGroupWithSubGroupsStructure,
|
||||
IIssueGroupedStructure,
|
||||
@ -54,14 +54,14 @@ export interface IModuleStore {
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
moduleId: string,
|
||||
data: Partial<ILinkDetails>
|
||||
data: ModuleLink
|
||||
) => Promise<ILinkDetails>;
|
||||
updateModuleLink: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
moduleId: string,
|
||||
linkId: string,
|
||||
data: Partial<ILinkDetails>
|
||||
data: ModuleLink
|
||||
) => Promise<ILinkDetails>;
|
||||
deleteModuleLink: (workspaceSlug: string, projectId: string, moduleId: string, linkId: string) => Promise<void>;
|
||||
|
||||
@ -309,12 +309,7 @@ export class ModuleStore implements IModuleStore {
|
||||
}
|
||||
};
|
||||
|
||||
createModuleLink = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
moduleId: string,
|
||||
data: Partial<ILinkDetails>
|
||||
) => {
|
||||
createModuleLink = async (workspaceSlug: string, projectId: string, moduleId: string, data: ModuleLink) => {
|
||||
try {
|
||||
const response = await this.moduleService.createModuleLink(workspaceSlug, projectId, moduleId, data);
|
||||
|
||||
@ -354,7 +349,7 @@ export class ModuleStore implements IModuleStore {
|
||||
projectId: string,
|
||||
moduleId: string,
|
||||
linkId: string,
|
||||
data: Partial<ILinkDetails>
|
||||
data: ModuleLink
|
||||
) => {
|
||||
try {
|
||||
const response = await this.moduleService.updateModuleLink(workspaceSlug, projectId, moduleId, linkId, data);
|
||||
|
Loading…
Reference in New Issue
Block a user