cancel issues API call when new call are being made (#4785)

This commit is contained in:
rahulramesha 2024-06-12 18:27:33 +05:30 committed by GitHub
parent 7677f021a9
commit 060fe8ebcc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 135 additions and 63 deletions

View File

@ -2,7 +2,7 @@
import { API_BASE_URL } from "@/helpers/common.helper";
import { APIService } from "@/services/api.service";
// types
import type { CycleDateCheckData, ICycle, TIssue, TIssuesResponse } from "@plane/types";
import type { CycleDateCheckData, ICycle, TIssuesResponse } from "@plane/types";
// helpers
export class CycleService extends APIService {
@ -50,11 +50,16 @@ export class CycleService extends APIService {
workspaceSlug: string,
projectId: string,
cycleId: string,
queries?: any
queries?: any,
config = {}
): Promise<TIssuesResponse> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/cycle-issues/`, {
params: queries,
})
return this.get(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/cycle-issues/`,
{
params: queries,
},
config
)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;

View File

@ -18,10 +18,14 @@ export class IssueService extends APIService {
});
}
async getIssues(workspaceSlug: string, projectId: string, queries?: any): Promise<TIssuesResponse> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/`, {
params: queries,
})
async getIssues(workspaceSlug: string, projectId: string, queries?: any, config = {}): Promise<TIssuesResponse> {
return this.get(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issues/`,
{
params: queries,
},
config
)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;

View File

@ -9,10 +9,14 @@ export class IssueArchiveService extends APIService {
super(API_BASE_URL);
}
async getArchivedIssues(workspaceSlug: string, projectId: string, queries?: any): Promise<any> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/archived-issues/`, {
params: { ...queries },
})
async getArchivedIssues(workspaceSlug: string, projectId: string, queries?: any, config = {}): Promise<any> {
return this.get(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/archived-issues/`,
{
params: { ...queries },
},
config
)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;

View File

@ -8,10 +8,14 @@ export class IssueDraftService extends APIService {
super(API_BASE_URL);
}
async getDraftIssues(workspaceSlug: string, projectId: string, query?: any): Promise<TIssuesResponse> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/`, {
params: { ...query },
})
async getDraftIssues(workspaceSlug: string, projectId: string, query?: any, config = {}): Promise<TIssuesResponse> {
return this.get(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/issue-drafts/`,
{
params: { ...query },
},
config
)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;

View File

@ -74,11 +74,16 @@ export class ModuleService extends APIService {
workspaceSlug: string,
projectId: string,
moduleId: string,
queries?: any
queries?: any,
config = {}
): Promise<TIssuesResponse> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/issues/`, {
params: queries,
})
return this.get(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/issues/`,
{
params: queries,
},
config
)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;

View File

@ -206,10 +206,19 @@ export class UserService extends APIService {
});
}
async getUserProfileIssues(workspaceSlug: string, userId: string, params: any): Promise<TIssuesResponse> {
return this.get(`/api/workspaces/${workspaceSlug}/user-issues/${userId}/`, {
params,
})
async getUserProfileIssues(
workspaceSlug: string,
userId: string,
params: any,
config = {}
): Promise<TIssuesResponse> {
return this.get(
`/api/workspaces/${workspaceSlug}/user-issues/${userId}/`,
{
params,
},
config
)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;

View File

@ -257,10 +257,14 @@ export class WorkspaceService extends APIService {
});
}
async getViewIssues(workspaceSlug: string, params: any): Promise<TIssuesResponse> {
return this.get(`/api/workspaces/${workspaceSlug}/issues/`, {
params,
})
async getViewIssues(workspaceSlug: string, params: any, config = {}): Promise<TIssuesResponse> {
return this.get(
`/api/workspaces/${workspaceSlug}/issues/`,
{
params,
},
config
)
.then((response) => response?.data)
.catch((error) => {
throw error?.response?.data;

View File

@ -83,19 +83,22 @@ export class ArchivedIssues extends BaseIssuesStore implements IArchivedIssues {
workspaceSlug: string,
projectId: string,
loadType: TLoader = "init-loader",
options: IssuePaginationOptions
options: IssuePaginationOptions,
isExistingPaginationOptions: boolean = false
) => {
try {
// set loader and clear store
runInAction(() => {
this.setLoader(loadType);
});
this.clear();
this.clear(!isExistingPaginationOptions);
// get params from pagination options
const params = this.issueFilterStore?.getFilterParams(options, undefined, undefined, undefined);
// call the fetch issues API with the params
const response = await this.issueArchiveService.getArchivedIssues(workspaceSlug, projectId, params);
const response = await this.issueArchiveService.getArchivedIssues(workspaceSlug, projectId, params, {
signal: this.controller.signal,
});
// after fetching issues, call the base method to process the response further
this.onfetchIssues(response, options, workspaceSlug, projectId);
@ -159,7 +162,7 @@ export class ArchivedIssues extends BaseIssuesStore implements IArchivedIssues {
loadType: TLoader = "mutation"
) => {
if (!this.paginationOptions) return;
return await this.fetchIssues(workspaceSlug, projectId, loadType, this.paginationOptions);
return await this.fetchIssues(workspaceSlug, projectId, loadType, this.paginationOptions, true);
};
/**

View File

@ -150,19 +150,22 @@ export class CycleIssues extends BaseIssuesStore implements ICycleIssues {
projectId: string,
loadType: TLoader,
options: IssuePaginationOptions,
cycleId: string
cycleId: string,
isExistingPaginationOptions: boolean = false
) => {
try {
// set loader and clear store
runInAction(() => {
this.setLoader(loadType);
});
this.clear();
this.clear(!isExistingPaginationOptions);
// get params from pagination options
const params = this.issueFilterStore?.getFilterParams(options, undefined, undefined, undefined);
// call the fetch issues API with the params
const response = await this.cycleService.getCycleIssues(workspaceSlug, projectId, cycleId, params);
const response = await this.cycleService.getCycleIssues(workspaceSlug, projectId, cycleId, params, {
signal: this.controller.signal,
});
// after fetching issues, call the base method to process the response further
this.onfetchIssues(response, options, workspaceSlug, projectId, cycleId);
@ -235,7 +238,7 @@ export class CycleIssues extends BaseIssuesStore implements ICycleIssues {
cycleId: string
) => {
if (!this.paginationOptions) return;
return await this.fetchIssues(workspaceSlug, projectId, loadType, this.paginationOptions, cycleId);
return await this.fetchIssues(workspaceSlug, projectId, loadType, this.paginationOptions, cycleId, true);
};
/**

View File

@ -81,19 +81,22 @@ export class DraftIssues extends BaseIssuesStore implements IDraftIssues {
workspaceSlug: string,
projectId: string,
loadType: TLoader = "init-loader",
options: IssuePaginationOptions
options: IssuePaginationOptions,
isExistingPaginationOptions: boolean = false
) => {
try {
// set loader and clear store
runInAction(() => {
this.setLoader(loadType);
});
this.clear();
this.clear(!isExistingPaginationOptions);
// get params from pagination options
const params = this.issueFilterStore?.getFilterParams(options, undefined, undefined, undefined);
// call the fetch issues API with the params
const response = await this.issueDraftService.getDraftIssues(workspaceSlug, projectId, params);
const response = await this.issueDraftService.getDraftIssues(workspaceSlug, projectId, params, {
signal: this.controller.signal,
});
// after fetching issues, call the base method to process the response further
this.onfetchIssues(response, options, workspaceSlug, projectId);
@ -157,7 +160,7 @@ export class DraftIssues extends BaseIssuesStore implements IDraftIssues {
loadType: TLoader = "mutation"
) => {
if (!this.paginationOptions) return;
return await this.fetchIssues(workspaceSlug, projectId, loadType, this.paginationOptions);
return await this.fetchIssues(workspaceSlug, projectId, loadType, this.paginationOptions, true);
};
createIssue = this.createDraftIssue;

View File

@ -187,6 +187,8 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
// root store
rootIssueStore;
issueFilterStore;
// API Abort controller
controller: AbortController;
constructor(_rootStore: IIssueRootStore, issueFilterStore: IBaseIssueFilterStore, isArchived = false) {
makeObservable(this, {
@ -246,6 +248,8 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
this.issueDraftService = new IssueDraftService();
this.moduleService = new ModuleService();
this.cycleService = new CycleService();
this.controller = new AbortController();
}
// Abstract class to be implemented to fetch parent stats such as project, module or cycle details
@ -1096,13 +1100,17 @@ export abstract class BaseIssuesStore implements IBaseIssuesStore {
/**
* Method called to clear out the current store
*/
clear() {
clear(shouldClearPaginationOptions = true) {
runInAction(() => {
this.groupedIssueIds = undefined;
this.issuePaginationData = {};
this.groupedIssueCount = {};
this.paginationOptions = undefined;
if (shouldClearPaginationOptions) {
this.paginationOptions = undefined;
}
});
this.controller.abort();
this.controller = new AbortController();
}
/**

View File

@ -105,19 +105,22 @@ export class ModuleIssues extends BaseIssuesStore implements IModuleIssues {
projectId: string,
loadType: TLoader,
options: IssuePaginationOptions,
moduleId: string
moduleId: string,
isExistingPaginationOptions: boolean = false
) => {
try {
// set loader and clear store
runInAction(() => {
this.setLoader(loadType);
});
this.clear();
this.clear(!isExistingPaginationOptions);
// get params from pagination options
const params = this.issueFilterStore?.getFilterParams(options, undefined, undefined, undefined);
// call the fetch issues API with the params
const response = await this.moduleService.getModuleIssues(workspaceSlug, projectId, moduleId, params);
const response = await this.moduleService.getModuleIssues(workspaceSlug, projectId, moduleId, params, {
signal: this.controller.signal,
});
// after fetching issues, call the base method to process the response further
this.onfetchIssues(response, options, workspaceSlug, projectId, moduleId);
@ -190,7 +193,7 @@ export class ModuleIssues extends BaseIssuesStore implements IModuleIssues {
moduleId: string
) => {
if (!this.paginationOptions) return;
return await this.fetchIssues(workspaceSlug, projectId, loadType, this.paginationOptions, moduleId);
return await this.fetchIssues(workspaceSlug, projectId, loadType, this.paginationOptions, moduleId, true);
};
/**

View File

@ -105,14 +105,15 @@ export class ProfileIssues extends BaseIssuesStore implements IProfileIssues {
userId: string,
loadType: TLoader,
options: IssuePaginationOptions,
view: "assigned" | "created" | "subscribed"
view: "assigned" | "created" | "subscribed",
isExistingPaginationOptions: boolean = false
) => {
try {
// set loader and clear store
runInAction(() => {
this.setLoader(loadType);
});
this.clear();
this.clear(!isExistingPaginationOptions);
// set ViewId
this.setViewId(view);
@ -131,7 +132,9 @@ export class ProfileIssues extends BaseIssuesStore implements IProfileIssues {
else if (this.currentView === "subscribed") params = { ...params, subscriber: userId };
// call the fetch issues API with the params
const response = await this.userService.getUserProfileIssues(workspaceSlug, userId, params);
const response = await this.userService.getUserProfileIssues(workspaceSlug, userId, params, {
signal: this.controller.signal,
});
// after fetching issues, call the base method to process the response further
this.onfetchIssues(response, options, workspaceSlug);
@ -201,7 +204,7 @@ export class ProfileIssues extends BaseIssuesStore implements IProfileIssues {
*/
fetchIssuesWithExistingPagination = async (workspaceSlug: string, userId: string, loadType: TLoader) => {
if (!this.paginationOptions || !this.currentView) return;
return await this.fetchIssues(workspaceSlug, userId, loadType, this.paginationOptions, this.currentView);
return await this.fetchIssues(workspaceSlug, userId, loadType, this.paginationOptions, this.currentView, true);
};
archiveBulkIssues = this.bulkArchiveIssues;

View File

@ -79,19 +79,22 @@ export class ProjectViewIssues extends BaseIssuesStore implements IProjectViewIs
workspaceSlug: string,
projectId: string,
loadType: TLoader,
options: IssuePaginationOptions
options: IssuePaginationOptions,
isExistingPaginationOptions: boolean = false
) => {
try {
// set loader and clear store
runInAction(() => {
this.setLoader(loadType);
});
this.clear();
this.clear(!isExistingPaginationOptions);
// get params from pagination options
const params = this.issueFilterStore?.getFilterParams(options, undefined, undefined, undefined);
// call the fetch issues API with the params
const response = await this.issueService.getIssues(workspaceSlug, projectId, params);
const response = await this.issueService.getIssues(workspaceSlug, projectId, params, {
signal: this.controller.signal,
});
// after fetching issues, call the base method to process the response further
this.onfetchIssues(response, options, workspaceSlug, projectId);
@ -151,7 +154,7 @@ export class ProjectViewIssues extends BaseIssuesStore implements IProjectViewIs
*/
fetchIssuesWithExistingPagination = async (workspaceSlug: string, projectId: string, loadType: TLoader) => {
if (!this.paginationOptions) return;
return await this.fetchIssues(workspaceSlug, projectId, loadType, this.paginationOptions);
return await this.fetchIssues(workspaceSlug, projectId, loadType, this.paginationOptions, true);
};
archiveBulkIssues = this.bulkArchiveIssues;

View File

@ -82,19 +82,22 @@ export class ProjectIssues extends BaseIssuesStore implements IProjectIssues {
workspaceSlug: string,
projectId: string,
loadType: TLoader = "init-loader",
options: IssuePaginationOptions
options: IssuePaginationOptions,
isExistingPaginationOptions: boolean = false
) => {
try {
// set loader and clear store
runInAction(() => {
this.setLoader(loadType);
});
this.clear();
this.clear(!isExistingPaginationOptions);
// get params from pagination options
const params = this.issueFilterStore?.getFilterParams(options, undefined, undefined, undefined);
// call the fetch issues API with the params
const response = await this.issueService.getIssues(workspaceSlug, projectId, params);
const response = await this.issueService.getIssues(workspaceSlug, projectId, params, {
signal: this.controller.signal,
});
// after fetching issues, call the base method to process the response further
this.onfetchIssues(response, options, workspaceSlug, projectId);
@ -158,7 +161,7 @@ export class ProjectIssues extends BaseIssuesStore implements IProjectIssues {
loadType: TLoader = "mutation"
) => {
if (!this.paginationOptions) return;
return await this.fetchIssues(workspaceSlug, projectId, loadType, this.paginationOptions);
return await this.fetchIssues(workspaceSlug, projectId, loadType, this.paginationOptions, true);
};
archiveBulkIssues = this.bulkArchiveIssues;

View File

@ -77,18 +77,26 @@ export class WorkspaceIssues extends BaseIssuesStore implements IWorkspaceIssues
* @param options
* @returns
*/
fetchIssues = async (workspaceSlug: string, viewId: string, loadType: TLoader, options: IssuePaginationOptions) => {
fetchIssues = async (
workspaceSlug: string,
viewId: string,
loadType: TLoader,
options: IssuePaginationOptions,
isExistingPaginationOptions: boolean = false
) => {
try {
// set loader and clear store
runInAction(() => {
this.setLoader(loadType);
});
this.clear();
this.clear(!isExistingPaginationOptions);
// get params from pagination options
const params = this.issueFilterStore?.getFilterParams(viewId, options, undefined, undefined, undefined);
// call the fetch issues API with the params
const response = await this.workspaceService.getViewIssues(workspaceSlug, params);
const response = await this.workspaceService.getViewIssues(workspaceSlug, params, {
signal: this.controller.signal,
});
// after fetching issues, call the base method to process the response further
this.onfetchIssues(response, options, workspaceSlug);
@ -149,7 +157,7 @@ export class WorkspaceIssues extends BaseIssuesStore implements IWorkspaceIssues
*/
fetchIssuesWithExistingPagination = async (workspaceSlug: string, viewId: string, loadType: TLoader) => {
if (!this.paginationOptions) return;
return await this.fetchIssues(workspaceSlug, viewId, loadType, this.paginationOptions);
return await this.fetchIssues(workspaceSlug, viewId, loadType, this.paginationOptions, true);
};
archiveBulkIssues = this.bulkArchiveIssues;