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 filteredOptions = currentProjectIncompleteCycleIds?.filter((optionId) => {
|
||||||
const cycleDetails = getCycleById(optionId);
|
const cycleDetails = getCycleById(optionId);
|
||||||
|
|
||||||
return cycleDetails?.name.toLowerCase().includes(query.toLowerCase());
|
return cycleDetails?.name?.toLowerCase().includes(query?.toLowerCase());
|
||||||
});
|
});
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
|
@ -160,7 +160,7 @@ export const IssueDetailRoot: FC<TIssueDetailRoot> = observer((props) => {
|
|||||||
},
|
},
|
||||||
addIssueToCycle: async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => {
|
addIssueToCycle: async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => {
|
||||||
try {
|
try {
|
||||||
const response = await addIssueToCycle(workspaceSlug, projectId, cycleId, issueIds);
|
await addIssueToCycle(workspaceSlug, projectId, cycleId, issueIds);
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
title: "Cycle added to issue successfully",
|
title: "Cycle added to issue successfully",
|
||||||
type: "success",
|
type: "success",
|
||||||
@ -168,7 +168,7 @@ export const IssueDetailRoot: FC<TIssueDetailRoot> = observer((props) => {
|
|||||||
});
|
});
|
||||||
captureIssueEvent({
|
captureIssueEvent({
|
||||||
eventName: ISSUE_UPDATED,
|
eventName: ISSUE_UPDATED,
|
||||||
payload: { ...response, state: "SUCCESS", element: "Issue detail page" },
|
payload: { ...issueIds, state: "SUCCESS", element: "Issue detail page" },
|
||||||
updates: {
|
updates: {
|
||||||
changed_property: "cycle_id",
|
changed_property: "cycle_id",
|
||||||
change_details: cycleId,
|
change_details: cycleId,
|
||||||
|
@ -60,13 +60,7 @@ export const CycleEmptyState: React.FC<Props> = observer((props) => {
|
|||||||
|
|
||||||
const issueIds = data.map((i) => i.id);
|
const issueIds = data.map((i) => i.id);
|
||||||
|
|
||||||
await issues
|
await issues.addIssueToCycle(workspaceSlug.toString(), projectId, cycleId.toString(), issueIds).catch(() => {
|
||||||
.addIssueToCycle(workspaceSlug.toString(), projectId, cycleId.toString(), issueIds)
|
|
||||||
.then((res) => {
|
|
||||||
updateIssue(workspaceSlug, projectId, res.id, res);
|
|
||||||
fetchIssue(workspaceSlug, projectId, res.id);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
type: "error",
|
type: "error",
|
||||||
title: "Error!",
|
title: "Error!",
|
||||||
|
@ -146,7 +146,7 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
|
|||||||
},
|
},
|
||||||
addIssueToCycle: async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => {
|
addIssueToCycle: async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => {
|
||||||
try {
|
try {
|
||||||
const response = await addIssueToCycle(workspaceSlug, projectId, cycleId, issueIds);
|
await addIssueToCycle(workspaceSlug, projectId, cycleId, issueIds);
|
||||||
setToastAlert({
|
setToastAlert({
|
||||||
title: "Cycle added to issue successfully",
|
title: "Cycle added to issue successfully",
|
||||||
type: "success",
|
type: "success",
|
||||||
@ -154,7 +154,7 @@ export const IssuePeekOverview: FC<IIssuePeekOverview> = observer((props) => {
|
|||||||
});
|
});
|
||||||
captureIssueEvent({
|
captureIssueEvent({
|
||||||
eventName: ISSUE_UPDATED,
|
eventName: ISSUE_UPDATED,
|
||||||
payload: { ...response, state: "SUCCESS", element: "Issue peek-overview" },
|
payload: { ...issueIds, state: "SUCCESS", element: "Issue peek-overview" },
|
||||||
updates: {
|
updates: {
|
||||||
changed_property: "cycle_id",
|
changed_property: "cycle_id",
|
||||||
change_details: cycleId,
|
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[]> {
|
async getIssueActivities(workspaceSlug: string, projectId: string, issueId: string): Promise<TIssueActivity[]> {
|
||||||
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/history/`)
|
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/${issueId}/history/`)
|
||||||
.then((response) => response?.data)
|
.then((response) => response?.data)
|
||||||
|
@ -54,7 +54,13 @@ export interface ICycleIssues {
|
|||||||
data: TIssue,
|
data: TIssue,
|
||||||
cycleId?: string | undefined
|
cycleId?: string | undefined
|
||||||
) => Promise<TIssue>;
|
) => 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>;
|
removeIssueFromCycle: (workspaceSlug: string, projectId: string, cycleId: string, issueId: string) => Promise<TIssue>;
|
||||||
transferIssuesFromCycle: (
|
transferIssuesFromCycle: (
|
||||||
workspaceSlug: string,
|
workspaceSlug: string,
|
||||||
@ -182,7 +188,7 @@ export class CycleIssues extends IssueHelperStore implements ICycleIssues {
|
|||||||
if (!cycleId) throw new Error("Cycle Id is required");
|
if (!cycleId) throw new Error("Cycle Id is required");
|
||||||
|
|
||||||
const response = await this.rootIssueStore.projectIssues.createIssue(workspaceSlug, projectId, data);
|
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);
|
this.rootIssueStore.rootStore.cycle.fetchCycleDetails(workspaceSlug, projectId, cycleId);
|
||||||
|
|
||||||
return response;
|
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 {
|
try {
|
||||||
const issueToCycle = await this.issueService.addIssueToCycle(workspaceSlug, projectId, cycleId, {
|
await this.issueService.addIssueToCycle(workspaceSlug, projectId, cycleId, {
|
||||||
issues: issueIds,
|
issues: issueIds,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (fetchAddedIssues) await this.rootIssueStore.issues.getIssues(workspaceSlug, projectId, issueIds);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
update(this.issues, cycleId, (cycleIssueIds = []) => uniq(concat(cycleIssueIds, issueIds)));
|
update(this.issues, cycleId, (cycleIssueIds = []) => uniq(concat(cycleIssueIds, issueIds)));
|
||||||
});
|
});
|
||||||
issueIds.forEach((issueId) => {
|
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.rootStore.issues.updateIssue(issueId, { cycle_id: cycleId });
|
||||||
});
|
});
|
||||||
this.rootIssueStore.rootStore.cycle.fetchCycleDetails(workspaceSlug, projectId, cycleId);
|
this.rootIssueStore.rootStore.cycle.fetchCycleDetails(workspaceSlug, projectId, cycleId);
|
||||||
|
|
||||||
return issueToCycle;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ export interface IIssueStoreActions {
|
|||||||
fetchIssue: (workspaceSlug: string, projectId: string, issueId: string, isArchived?: boolean) => Promise<TIssue>;
|
fetchIssue: (workspaceSlug: string, projectId: string, issueId: string, isArchived?: boolean) => Promise<TIssue>;
|
||||||
updateIssue: (workspaceSlug: string, projectId: string, issueId: string, data: Partial<TIssue>) => Promise<TIssue>;
|
updateIssue: (workspaceSlug: string, projectId: string, issueId: string, data: Partial<TIssue>) => Promise<TIssue>;
|
||||||
removeIssue: (workspaceSlug: string, projectId: string, issueId: string) => 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>;
|
removeIssueFromCycle: (workspaceSlug: string, projectId: string, cycleId: string, issueId: string) => Promise<TIssue>;
|
||||||
addModulesToIssue: (workspaceSlug: string, projectId: string, issueId: string, moduleIds: string[]) => Promise<any>;
|
addModulesToIssue: (workspaceSlug: string, projectId: string, issueId: string, moduleIds: string[]) => Promise<any>;
|
||||||
removeModulesFromIssue: (
|
removeModulesFromIssue: (
|
||||||
@ -123,15 +123,15 @@ export class IssueStore implements IIssueStore {
|
|||||||
this.rootIssueDetailStore.rootIssueStore.projectIssues.removeIssue(workspaceSlug, projectId, issueId);
|
this.rootIssueDetailStore.rootIssueStore.projectIssues.removeIssue(workspaceSlug, projectId, issueId);
|
||||||
|
|
||||||
addIssueToCycle = async (workspaceSlug: string, projectId: string, cycleId: string, issueIds: string[]) => {
|
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,
|
workspaceSlug,
|
||||||
projectId,
|
projectId,
|
||||||
cycleId,
|
cycleId,
|
||||||
issueIds
|
issueIds,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
if (issueIds && issueIds.length > 0)
|
if (issueIds && issueIds.length > 0)
|
||||||
await this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueIds[0]);
|
await this.rootIssueDetailStore.activity.fetchActivities(workspaceSlug, projectId, issueIds[0]);
|
||||||
return cycle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
removeIssueFromCycle = async (workspaceSlug: string, projectId: string, cycleId: string, issueId: string) => {
|
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";
|
import { computedFn } from "mobx-utils";
|
||||||
// types
|
// types
|
||||||
import { TIssue } from "@plane/types";
|
import { TIssue } from "@plane/types";
|
||||||
|
//services
|
||||||
|
import { IssueService } from "services/issue";
|
||||||
|
|
||||||
export type IIssueStore = {
|
export type IIssueStore = {
|
||||||
// observables
|
// observables
|
||||||
issuesMap: Record<string, TIssue>; // Record defines issue_id as key and TIssue as value
|
issuesMap: Record<string, TIssue>; // Record defines issue_id as key and TIssue as value
|
||||||
// actions
|
// actions
|
||||||
|
getIssues(workspaceSlug: string, projectId: string, issueIds: string[]): Promise<TIssue[]>;
|
||||||
addIssue(issues: TIssue[], shouldReplace?: boolean): void;
|
addIssue(issues: TIssue[], shouldReplace?: boolean): void;
|
||||||
updateIssue(issueId: string, issue: Partial<TIssue>): void;
|
updateIssue(issueId: string, issue: Partial<TIssue>): void;
|
||||||
removeIssue(issueId: string): void;
|
removeIssue(issueId: string): void;
|
||||||
@ -21,6 +24,8 @@ export type IIssueStore = {
|
|||||||
export class IssueStore implements IIssueStore {
|
export class IssueStore implements IIssueStore {
|
||||||
// observables
|
// observables
|
||||||
issuesMap: { [issue_id: string]: TIssue } = {};
|
issuesMap: { [issue_id: string]: TIssue } = {};
|
||||||
|
// service
|
||||||
|
issueService;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
makeObservable(this, {
|
makeObservable(this, {
|
||||||
@ -31,6 +36,8 @@ export class IssueStore implements IIssueStore {
|
|||||||
updateIssue: action,
|
updateIssue: action,
|
||||||
removeIssue: action,
|
removeIssue: action,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.issueService = new IssueService();
|
||||||
}
|
}
|
||||||
|
|
||||||
// actions
|
// 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
|
* @description This method will update the issue in the issuesMap
|
||||||
* @param {string} issueId
|
* @param {string} issueId
|
||||||
|
@ -52,7 +52,13 @@ export interface IModuleIssues {
|
|||||||
data: TIssue,
|
data: TIssue,
|
||||||
moduleId?: string | undefined
|
moduleId?: string | undefined
|
||||||
) => Promise<TIssue | 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: (
|
removeIssuesFromModule: (
|
||||||
workspaceSlug: string,
|
workspaceSlug: string,
|
||||||
projectId: string,
|
projectId: string,
|
||||||
@ -187,7 +193,7 @@ export class ModuleIssues extends IssueHelperStore implements IModuleIssues {
|
|||||||
if (!moduleId) throw new Error("Module Id is required");
|
if (!moduleId) throw new Error("Module Id is required");
|
||||||
|
|
||||||
const response = await this.rootIssueStore.projectIssues.createIssue(workspaceSlug, projectId, data);
|
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);
|
this.rootIssueStore.rootStore.module.fetchModuleDetails(workspaceSlug, projectId, moduleId);
|
||||||
|
|
||||||
return response;
|
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 {
|
try {
|
||||||
const issueToModule = await this.moduleService.addIssuesToModule(workspaceSlug, projectId, moduleId, {
|
await this.moduleService.addIssuesToModule(workspaceSlug, projectId, moduleId, {
|
||||||
issues: issueIds,
|
issues: issueIds,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (fetchAddedIssues) await this.rootIssueStore.issues.getIssues(workspaceSlug, projectId, issueIds);
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
update(this.issues, moduleId, (moduleIssueIds = []) => {
|
update(this.issues, moduleId, (moduleIssueIds = []) => {
|
||||||
if (!moduleIssueIds) return [...issueIds];
|
if (!moduleIssueIds) return [...issueIds];
|
||||||
@ -289,8 +303,6 @@ export class ModuleIssues extends IssueHelperStore implements IModuleIssues {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.rootIssueStore.rootStore.module.fetchModuleDetails(workspaceSlug, projectId, moduleId);
|
this.rootIssueStore.rootStore.module.fetchModuleDetails(workspaceSlug, projectId, moduleId);
|
||||||
|
|
||||||
return issueToModule;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user