mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
Merge pull request #339 from makeplane/chore/new_link_endpoint
chore: new link endpoints
This commit is contained in:
commit
3af3bb0fb5
@ -16,7 +16,7 @@ import type { IIssueLink, ModuleLink } from "types";
|
||||
type Props = {
|
||||
isOpen: boolean;
|
||||
handleClose: () => void;
|
||||
onFormSubmit: (formData: IIssueLink | ModuleLink) => void;
|
||||
onFormSubmit: (formData: IIssueLink | ModuleLink) => Promise<void>;
|
||||
};
|
||||
|
||||
const defaultValues: ModuleLink = {
|
||||
|
@ -14,6 +14,7 @@ type Props = {
|
||||
created_at: Date;
|
||||
created_by: string;
|
||||
created_by_detail: IUserLite;
|
||||
metadata: any;
|
||||
title: string;
|
||||
url: string;
|
||||
}[];
|
||||
@ -56,8 +57,8 @@ export const LinksList: React.FC<Props> = ({ links, handleDeleteLink, userAuth }
|
||||
<h5 className="w-4/5">{link.title}</h5>
|
||||
<p className="mt-0.5 text-gray-500">
|
||||
Added {timeAgo(link.created_at)}
|
||||
{/* <br />
|
||||
by {link.created_by_detail.email} */}
|
||||
<br />
|
||||
by {link.created_by_detail.email}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
|
@ -86,7 +86,7 @@ export const CreateUpdateIssueModal: React.FC<IssuesModalProps> = ({
|
||||
return () => {
|
||||
window.removeEventListener("keydown", handleKeyDown);
|
||||
};
|
||||
}, []);
|
||||
}, [handleClose]);
|
||||
|
||||
const addIssueToCycle = async (issueId: string, cycleId: string) => {
|
||||
if (!workspaceSlug || !projectId) return;
|
||||
|
@ -77,6 +77,17 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
|
||||
|
||||
const { setToastAlert } = useToast();
|
||||
|
||||
console.log("isseu details: ", issueDetail);
|
||||
|
||||
// const { data: issueLinks } = useSWR(
|
||||
// workspaceSlug && projectId
|
||||
// ? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string)
|
||||
// : null,
|
||||
// workspaceSlug && projectId
|
||||
// ? () => issuesService.getIssues(workspaceSlug as string, projectId as string)
|
||||
// : null
|
||||
// );
|
||||
|
||||
const { data: issues } = useSWR(
|
||||
workspaceSlug && projectId
|
||||
? PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string)
|
||||
@ -149,16 +160,12 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
|
||||
const handleCreateLink = async (formData: IIssueLink) => {
|
||||
if (!workspaceSlug || !projectId || !issueDetail) return;
|
||||
|
||||
const previousLinks = issueDetail?.issue_link.map((l) => ({ title: l.title, url: l.url }));
|
||||
|
||||
const payload: Partial<IIssue> = {
|
||||
links_list: [...(previousLinks ?? []), formData],
|
||||
};
|
||||
const payload = { metadata: {}, ...formData };
|
||||
|
||||
await issuesService
|
||||
.patchIssue(workspaceSlug as string, projectId as string, issueDetail.id, payload)
|
||||
.createIssueLink(workspaceSlug as string, projectId as string, issueDetail.id, payload)
|
||||
.then((res) => {
|
||||
mutate(ISSUE_DETAILS(issueDetail.id as string));
|
||||
mutate(ISSUE_DETAILS(issueDetail.id));
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
@ -171,17 +178,15 @@ export const IssueDetailsSidebar: React.FC<Props> = ({
|
||||
const updatedLinks = issueDetail.issue_link.filter((l) => l.id !== linkId);
|
||||
|
||||
mutate<IIssue>(
|
||||
ISSUE_DETAILS(issueDetail.id as string),
|
||||
ISSUE_DETAILS(issueDetail.id),
|
||||
(prevData) => ({ ...(prevData as IIssue), issue_link: updatedLinks }),
|
||||
false
|
||||
);
|
||||
|
||||
await issuesService
|
||||
.patchIssue(workspaceSlug as string, projectId as string, issueDetail.id, {
|
||||
links_list: updatedLinks,
|
||||
})
|
||||
.deleteIssueLink(workspaceSlug as string, projectId as string, issueDetail.id, linkId)
|
||||
.then((res) => {
|
||||
mutate(ISSUE_DETAILS(issueDetail.id as string));
|
||||
mutate(ISSUE_DETAILS(issueDetail.id));
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
|
@ -71,6 +71,8 @@ export const ModuleDetailsSidebar: React.FC<Props> = ({
|
||||
const [startDateRange, setStartDateRange] = useState<Date | null>(new Date());
|
||||
const [endDateRange, setEndDateRange] = useState<Date | null>(null);
|
||||
|
||||
console.log("module details: ", module);
|
||||
|
||||
const router = useRouter();
|
||||
const { workspaceSlug, projectId, moduleId } = router.query;
|
||||
|
||||
@ -115,14 +117,10 @@ export const ModuleDetailsSidebar: React.FC<Props> = ({
|
||||
const handleCreateLink = async (formData: ModuleLink) => {
|
||||
if (!workspaceSlug || !projectId || !moduleId) return;
|
||||
|
||||
const previousLinks = module?.link_module.map((l) => ({ title: l.title, url: l.url }));
|
||||
|
||||
const payload: Partial<IModule> = {
|
||||
links_list: [...(previousLinks ?? []), formData],
|
||||
};
|
||||
const payload = { metadata: {}, ...formData };
|
||||
|
||||
await modulesService
|
||||
.patchModule(workspaceSlug as string, projectId as string, moduleId as string, payload)
|
||||
.createModuleLink(workspaceSlug as string, projectId as string, moduleId as string, payload)
|
||||
.then((res) => {
|
||||
mutate(MODULE_DETAILS(moduleId as string));
|
||||
})
|
||||
@ -135,11 +133,25 @@ export const ModuleDetailsSidebar: React.FC<Props> = ({
|
||||
});
|
||||
};
|
||||
|
||||
const handleDeleteLink = (linkId: string) => {
|
||||
if (!module) return;
|
||||
const handleDeleteLink = async (linkId: string) => {
|
||||
if (!workspaceSlug || !projectId || !module) return;
|
||||
|
||||
const updatedLinks = module.link_module.filter((l) => l.id !== linkId);
|
||||
submitChanges({ links_list: updatedLinks });
|
||||
|
||||
mutate<IModule>(
|
||||
MODULE_DETAILS(module.id),
|
||||
(prevData) => ({ ...(prevData as IModule), link_module: updatedLinks }),
|
||||
false
|
||||
);
|
||||
|
||||
await modulesService
|
||||
.deleteModuleLink(workspaceSlug as string, projectId as string, module.id, linkId)
|
||||
.then((res) => {
|
||||
mutate(MODULE_DETAILS(module.id));
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@ -350,27 +362,6 @@ export const ModuleDetailsSidebar: React.FC<Props> = ({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="py-1">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<h4>Links</h4>
|
||||
<button
|
||||
type="button"
|
||||
className="grid h-7 w-7 place-items-center rounded p-1 outline-none duration-300 hover:bg-gray-100"
|
||||
onClick={() => setModuleLinkModal(true)}
|
||||
>
|
||||
<PlusIcon className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="mt-2 space-y-2">
|
||||
{module.link_module && module.link_module.length > 0 ? (
|
||||
<LinksList
|
||||
links={module.link_module}
|
||||
handleDeleteLink={handleDeleteLink}
|
||||
userAuth={userAuth}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center w-full gap-2">
|
||||
{isStartValid && isEndValid ? (
|
||||
@ -388,6 +379,27 @@ export const ModuleDetailsSidebar: React.FC<Props> = ({
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
<div className="py-1 text-xs">
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<h4>Links</h4>
|
||||
<button
|
||||
type="button"
|
||||
className="grid h-7 w-7 place-items-center rounded p-1 outline-none duration-300 hover:bg-gray-100"
|
||||
onClick={() => setModuleLinkModal(true)}
|
||||
>
|
||||
<PlusIcon className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="mt-2 space-y-2">
|
||||
{module.link_module && module.link_module.length > 0 ? (
|
||||
<LinksList
|
||||
links={module.link_module}
|
||||
handleDeleteLink={handleDeleteLink}
|
||||
userAuth={userAuth}
|
||||
/>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<Loader>
|
||||
|
@ -293,6 +293,41 @@ class ProjectIssuesServices extends APIService {
|
||||
throw error?.response?.data;
|
||||
});
|
||||
}
|
||||
|
||||
async createIssueLink(
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
data: {
|
||||
metadata: any;
|
||||
title: string;
|
||||
url: string;
|
||||
}
|
||||
): Promise<any> {
|
||||
return this.post(
|
||||
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-links/`,
|
||||
data
|
||||
)
|
||||
.then((response) => response?.data)
|
||||
.catch((error) => {
|
||||
throw error?.response?.data;
|
||||
});
|
||||
}
|
||||
|
||||
async deleteIssueLink(
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
issueId: string,
|
||||
linkId: string
|
||||
): Promise<any> {
|
||||
return this.delete(
|
||||
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/issue-links/${linkId}/`
|
||||
)
|
||||
.then((response) => response?.data)
|
||||
.catch((error) => {
|
||||
throw error?.response?.data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default new ProjectIssuesServices();
|
||||
|
@ -116,6 +116,41 @@ class ProjectIssuesServices extends APIService {
|
||||
throw error?.response?.data;
|
||||
});
|
||||
}
|
||||
|
||||
async createModuleLink(
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
moduleId: string,
|
||||
data: {
|
||||
metadata: any;
|
||||
title: string;
|
||||
url: string;
|
||||
}
|
||||
): Promise<any> {
|
||||
return this.post(
|
||||
`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/module-links/`,
|
||||
data
|
||||
)
|
||||
.then((response) => response?.data)
|
||||
.catch((error) => {
|
||||
throw error?.response?.data;
|
||||
});
|
||||
}
|
||||
|
||||
async deleteModuleLink(
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
moduleId: string,
|
||||
linkId: string
|
||||
): Promise<any> {
|
||||
return this.delete(
|
||||
`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/module-links/${linkId}/`
|
||||
)
|
||||
.then((response) => response?.data)
|
||||
.catch((error) => {
|
||||
throw error?.response?.data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default new ProjectIssuesServices();
|
||||
|
1
apps/app/types/issues.d.ts
vendored
1
apps/app/types/issues.d.ts
vendored
@ -82,6 +82,7 @@ export interface IIssue {
|
||||
created_by: string;
|
||||
created_by_detail: IUserLite;
|
||||
id: string;
|
||||
metadata: any;
|
||||
title: string;
|
||||
url: string;
|
||||
}[];
|
||||
|
1
apps/app/types/modules.d.ts
vendored
1
apps/app/types/modules.d.ts
vendored
@ -14,6 +14,7 @@ export interface IModule {
|
||||
created_by: string;
|
||||
created_by_detail: IUserLite;
|
||||
id: string;
|
||||
metadata: any;
|
||||
title: string;
|
||||
url: string;
|
||||
}[];
|
||||
|
Loading…
Reference in New Issue
Block a user