mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
modify adding issues to modules and cycles
This commit is contained in:
parent
7078863189
commit
fa085bd29f
@ -56,7 +56,7 @@ export const TransferIssuesModal: React.FC<Props> = observer((props) => {
|
||||
const filteredOptions = currentProjectIncompleteCycleIds?.filter((optionId) => {
|
||||
const cycleDetails = getCycleById(optionId);
|
||||
|
||||
return cycleDetails?.name.toLowerCase().includes(query.toLowerCase());
|
||||
return cycleDetails?.name?.toLowerCase().includes(query?.toLowerCase());
|
||||
});
|
||||
|
||||
// useEffect(() => {
|
||||
|
@ -160,7 +160,7 @@ export const IssueDetailRoot: FC<TIssueDetailRoot> = observer((props) => {
|
||||
},
|
||||
addIssueToCycle: async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => {
|
||||
try {
|
||||
const response = await addIssueToCycle(workspaceSlug, projectId, cycleId, issueIds);
|
||||
await addIssueToCycle(workspaceSlug, projectId, cycleId, issueIds);
|
||||
setToastAlert({
|
||||
title: "Cycle added to issue successfully",
|
||||
type: "success",
|
||||
@ -168,7 +168,7 @@ export const IssueDetailRoot: FC<TIssueDetailRoot> = observer((props) => {
|
||||
});
|
||||
captureIssueEvent({
|
||||
eventName: ISSUE_UPDATED,
|
||||
payload: { ...response, state: "SUCCESS", element: "Issue detail page" },
|
||||
payload: { ...issueIds, state: "SUCCESS", element: "Issue detail page" },
|
||||
updates: {
|
||||
changed_property: "cycle_id",
|
||||
change_details: cycleId,
|
||||
|
@ -60,19 +60,13 @@ export const CycleEmptyState: React.FC<Props> = observer((props) => {
|
||||
|
||||
const issueIds = data.map((i) => i.id);
|
||||
|
||||
await issues
|
||||
.addIssueToCycle(workspaceSlug.toString(), projectId, cycleId.toString(), issueIds)
|
||||
.then((res) => {
|
||||
updateIssue(workspaceSlug, projectId, res.id, res);
|
||||
fetchIssue(workspaceSlug, projectId, res.id);
|
||||
})
|
||||
.catch(() => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "Selected issues could not be added to the cycle. Please try again.",
|
||||
});
|
||||
await issues.addIssueToCycle(workspaceSlug.toString(), projectId, cycleId.toString(), issueIds).catch(() => {
|
||||
setToastAlert({
|
||||
type: "error",
|
||||
title: "Error!",
|
||||
message: "Selected issues could not be added to the cycle. Please try again.",
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const emptyStateDetail = CYCLE_EMPTY_STATE_DETAILS["no-issues"];
|
||||
|
@ -146,7 +146,7 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
|
||||
},
|
||||
addIssueToCycle: async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => {
|
||||
try {
|
||||
const response = await addIssueToCycle(workspaceSlug, projectId, cycleId, issueIds);
|
||||
await addIssueToCycle(workspaceSlug, projectId, cycleId, issueIds);
|
||||
setToastAlert({
|
||||
title: "Cycle added to issue successfully",
|
||||
type: "success",
|
||||
@ -154,7 +154,7 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
|
||||
});
|
||||
captureIssueEvent({
|
||||
eventName: ISSUE_UPDATED,
|
||||
payload: { ...response, state: "SUCCESS", element: "Issue peek-overview" },
|
||||
payload: { ...issueIds, state: "SUCCESS", element: "Issue peek-overview" },
|
||||
updates: {
|
||||
changed_property: "cycle_id",
|
||||
change_details: cycleId,
|
||||
|
@ -59,6 +59,16 @@ export class IssueService extends APIService {
|
||||
});
|
||||
}
|
||||
|
||||
async retrieveIssues(workspaceSlug: string, projectId: string, issueIds: string[]): Promise<TIssue[]> {
|
||||
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/list/`, {
|
||||
params: { issues: issueIds.join(",") },
|
||||
})
|
||||
.then((response) => response?.data)
|
||||
.catch((error) => {
|
||||
throw error?.response?.data;
|
||||
});
|
||||
}
|
||||
|
||||
async getIssueActivities(workspaceSlug: string, projectId: string, issueId: string): Promise<TIssueActivity[]> {
|
||||
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/history/`)
|
||||
.then((response) => response?.data)
|
||||
|
@ -54,7 +54,13 @@ export interface ICycleIssues {
|
||||
data: TIssue,
|
||||
cycleId?: string | undefined
|
||||
) => Promise<TIssue>;
|
||||
addIssueToCycle: (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => Promise<TIssue>;
|
||||
addIssueToCycle: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
cycleId: string,
|
||||
issueIds: string[],
|
||||
fetchAddedIssues?: boolean
|
||||
) => Promise<void>;
|
||||
removeIssueFromCycle: (workspaceSlug: string, projectId: string, cycleId: string, issueId: string) => Promise<TIssue>;
|
||||
transferIssuesFromCycle: (
|
||||
workspaceSlug: string,
|
||||
@ -182,7 +188,7 @@ export class CycleIssues extends IssueHelperStore implements ICycleIssues {
|
||||
if (!cycleId) throw new Error("Cycle Id is required");
|
||||
|
||||
const response = await this.rootIssueStore.projectIssues.createIssue(workspaceSlug, projectId, data);
|
||||
await this.addIssueToCycle(workspaceSlug, projectId, cycleId, [response.id]);
|
||||
await this.addIssueToCycle(workspaceSlug, projectId, cycleId, [response.id], false);
|
||||
this.rootIssueStore.rootStore.cycle.fetchCycleDetails(workspaceSlug, projectId, cycleId);
|
||||
|
||||
return response;
|
||||
@ -265,21 +271,33 @@ export class CycleIssues extends IssueHelperStore implements ICycleIssues {
|
||||
}
|
||||
};
|
||||
|
||||
addIssueToCycle = async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => {
|
||||
addIssueToCycle = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
cycleId: string,
|
||||
issueIds: string[],
|
||||
fetchAddedIssues = true
|
||||
) => {
|
||||
try {
|
||||
const issueToCycle = await this.issueService.addIssueToCycle(workspaceSlug, projectId, cycleId, {
|
||||
await this.issueService.addIssueToCycle(workspaceSlug, projectId, cycleId, {
|
||||
issues: issueIds,
|
||||
});
|
||||
|
||||
if (fetchAddedIssues) await this.rootIssueStore.issues.getIssues(workspaceSlug, projectId, issueIds);
|
||||
|
||||
runInAction(() => {
|
||||
update(this.issues, cycleId, (cycleIssueIds = []) => uniq(concat(cycleIssueIds, issueIds)));
|
||||
});
|
||||
issueIds.forEach((issueId) => {
|
||||
const issueCycleId = this.rootIssueStore.issues.getIssueById(issueId)?.cycle_id;
|
||||
if (issueCycleId && issueCycleId !== cycleId) {
|
||||
runInAction(() => {
|
||||
pull(this.issues[issueCycleId], issueId);
|
||||
});
|
||||
}
|
||||
this.rootStore.issues.updateIssue(issueId, { cycle_id: cycleId });
|
||||
});
|
||||
this.rootIssueStore.rootStore.cycle.fetchCycleDetails(workspaceSlug, projectId, cycleId);
|
||||
|
||||
return issueToCycle;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ export interface IIssueStoreActions {
|
||||
fetchIssue: (workspaceSlug: string, projectId: string, issueId: string, isArchived?: boolean) => Promise<TIssue>;
|
||||
updateIssue: (workspaceSlug: string, projectId: string, issueId: string, data: Partial<TIssue>) => Promise<TIssue>;
|
||||
removeIssue: (workspaceSlug: string, projectId: string, issueId: string) => Promise<TIssue>;
|
||||
addIssueToCycle: (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => Promise<TIssue>;
|
||||
addIssueToCycle: (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => Promise<void>;
|
||||
removeIssueFromCycle: (workspaceSlug: string, projectId: string, cycleId: string, issueId: string) => Promise<TIssue>;
|
||||
addModulesToIssue: (workspaceSlug: string, projectId: string, issueId: string, moduleIds: string[]) => Promise<any>;
|
||||
removeModulesFromIssue: (
|
||||
@ -123,15 +123,15 @@ export class IssueStore implements IIssueStore {
|
||||
this.rootIssueDetailStore.rootIssueStore.projectIssues.removeIssue(workspaceSlug, projectId, issueId);
|
||||
|
||||
addIssueToCycle = async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => {
|
||||
const cycle = await this.rootIssueDetailStore.rootIssueStore.cycleIssues.addIssueToCycle(
|
||||
await this.rootIssueDetailStore.rootIssueStore.cycleIssues.addIssueToCycle(
|
||||
workspaceSlug,
|
||||
projectId,
|
||||
cycleId,
|
||||
issueIds
|
||||
issueIds,
|
||||
false
|
||||
);
|
||||
if (issueIds && issueIds.length > 0)
|
||||
await this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueIds[0]);
|
||||
return cycle;
|
||||
};
|
||||
|
||||
removeIssueFromCycle = async (workspaceSlug: string, projectId: string, cycleId: string, issueId: string) => {
|
||||
|
@ -5,11 +5,14 @@ import { action, makeObservable, observable, runInAction } from "mobx";
|
||||
import { computedFn } from "mobx-utils";
|
||||
// types
|
||||
import { TIssue } from "@plane/types";
|
||||
//services
|
||||
import { IssueService } from "services/issue";
|
||||
|
||||
export type IIssueStore = {
|
||||
// observables
|
||||
issuesMap: Record<string, TIssue>; // Record defines issue_id as key and TIssue as value
|
||||
// actions
|
||||
getIssues(workspaceSlug: string, projectId: string, issueIds: string[]): Promise<TIssue[]>;
|
||||
addIssue(issues: TIssue[], shouldReplace?: boolean): void;
|
||||
updateIssue(issueId: string, issue: Partial<TIssue>): void;
|
||||
removeIssue(issueId: string): void;
|
||||
@ -21,6 +24,8 @@ export type IIssueStore = {
|
||||
export class IssueStore implements IIssueStore {
|
||||
// observables
|
||||
issuesMap: { [issue_id: string]: TIssue } = {};
|
||||
// service
|
||||
issueService;
|
||||
|
||||
constructor() {
|
||||
makeObservable(this, {
|
||||
@ -31,6 +36,8 @@ export class IssueStore implements IIssueStore {
|
||||
updateIssue: action,
|
||||
removeIssue: action,
|
||||
});
|
||||
|
||||
this.issueService = new IssueService();
|
||||
}
|
||||
|
||||
// actions
|
||||
@ -48,6 +55,18 @@ export class IssueStore implements IIssueStore {
|
||||
});
|
||||
};
|
||||
|
||||
getIssues = async (workspaceSlug: string, projectId: string, issueIds: string[]) => {
|
||||
const issues = await this.issueService.retrieveIssues(workspaceSlug, projectId, issueIds);
|
||||
|
||||
runInAction(() => {
|
||||
issues.forEach((issue) => {
|
||||
if (!this.issuesMap[issue.id]) set(this.issuesMap, issue.id, issue);
|
||||
});
|
||||
});
|
||||
|
||||
return issues;
|
||||
};
|
||||
|
||||
/**
|
||||
* @description This method will update the issue in the issuesMap
|
||||
* @param {string} issueId
|
||||
|
@ -52,7 +52,13 @@ export interface IModuleIssues {
|
||||
data: TIssue,
|
||||
moduleId?: string | undefined
|
||||
) => Promise<TIssue | undefined>;
|
||||
addIssuesToModule: (workspaceSlug: string, projectId: string, moduleId: string, issueIds: string[]) => Promise<void>;
|
||||
addIssuesToModule: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
moduleId: string,
|
||||
issueIds: string[],
|
||||
fetchAddedIssues?: boolean
|
||||
) => Promise<void>;
|
||||
removeIssuesFromModule: (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
@ -187,7 +193,7 @@ export class ModuleIssues extends IssueHelperStore implements IModuleIssues {
|
||||
if (!moduleId) throw new Error("Module Id is required");
|
||||
|
||||
const response = await this.rootIssueStore.projectIssues.createIssue(workspaceSlug, projectId, data);
|
||||
await this.addIssuesToModule(workspaceSlug, projectId, moduleId, [response.id]);
|
||||
await this.addIssuesToModule(workspaceSlug, projectId, moduleId, [response.id], false);
|
||||
this.rootIssueStore.rootStore.module.fetchModuleDetails(workspaceSlug, projectId, moduleId);
|
||||
|
||||
return response;
|
||||
@ -269,12 +275,20 @@ export class ModuleIssues extends IssueHelperStore implements IModuleIssues {
|
||||
}
|
||||
};
|
||||
|
||||
addIssuesToModule = async (workspaceSlug: string, projectId: string, moduleId: string, issueIds: string[]) => {
|
||||
addIssuesToModule = async (
|
||||
workspaceSlug: string,
|
||||
projectId: string,
|
||||
moduleId: string,
|
||||
issueIds: string[],
|
||||
fetchAddedIssues = true
|
||||
) => {
|
||||
try {
|
||||
const issueToModule = await this.moduleService.addIssuesToModule(workspaceSlug, projectId, moduleId, {
|
||||
await this.moduleService.addIssuesToModule(workspaceSlug, projectId, moduleId, {
|
||||
issues: issueIds,
|
||||
});
|
||||
|
||||
if (fetchAddedIssues) await this.rootIssueStore.issues.getIssues(workspaceSlug, projectId, issueIds);
|
||||
|
||||
runInAction(() => {
|
||||
update(this.issues, moduleId, (moduleIssueIds = []) => {
|
||||
if (!moduleIssueIds) return [...issueIds];
|
||||
@ -289,8 +303,6 @@ export class ModuleIssues extends IssueHelperStore implements IModuleIssues {
|
||||
});
|
||||
});
|
||||
this.rootIssueStore.rootStore.module.fetchModuleDetails(workspaceSlug, projectId, moduleId);
|
||||
|
||||
return issueToModule;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user