feat: separate filters for cycles and modules (#892)

This commit is contained in:
Aaryan Khandelwal 2023-04-19 17:25:31 +05:30 committed by GitHub
parent 390b837561
commit c5206a7792
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 156 additions and 21 deletions

View File

@ -8,6 +8,8 @@ import useSWR, { mutate } from "swr";
import ToastAlert from "components/toast-alert"; import ToastAlert from "components/toast-alert";
// services // services
import projectService from "services/project.service"; import projectService from "services/project.service";
import cyclesService from "services/cycles.service";
import modulesService from "services/modules.service";
import viewsService from "services/views.service"; import viewsService from "services/views.service";
// types // types
import { import {
@ -18,7 +20,12 @@ import {
TIssueOrderByOptions, TIssueOrderByOptions,
} from "types"; } from "types";
// fetch-keys // fetch-keys
import { USER_PROJECT_VIEW, VIEW_DETAILS } from "constants/fetch-keys"; import {
CYCLE_DETAILS,
MODULE_DETAILS,
USER_PROJECT_VIEW,
VIEW_DETAILS,
} from "constants/fetch-keys";
export const issueViewContext = createContext<ContextType>({} as ContextType); export const issueViewContext = createContext<ContextType>({} as ContextType);
@ -171,7 +178,29 @@ const saveDataToServer = async (workspaceSlug: string, projectID: string, state:
}); });
}; };
const sendFilterDataToServer = async ( const saveCycleFilters = async (
workspaceSlug: string,
projectId: string,
cycleId: string,
state: any
) => {
await cyclesService.patchCycle(workspaceSlug, projectId, cycleId, {
...state,
});
};
const saveModuleFilters = async (
workspaceSlug: string,
projectId: string,
moduleId: string,
state: any
) => {
await modulesService.patchModule(workspaceSlug, projectId, moduleId, {
...state,
});
};
const saveViewFilters = async (
workspaceSlug: string, workspaceSlug: string,
projectId: string, projectId: string,
viewId: string, viewId: string,
@ -206,7 +235,7 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> =
const [state, dispatch] = useReducer(reducer, initialState); const [state, dispatch] = useReducer(reducer, initialState);
const router = useRouter(); const router = useRouter();
const { workspaceSlug, projectId, viewId } = router.query; const { workspaceSlug, projectId, cycleId, moduleId, viewId } = router.query;
const { data: myViewProps, mutate: mutateMyViewProps } = useSWR( const { data: myViewProps, mutate: mutateMyViewProps } = useSWR(
workspaceSlug && projectId ? USER_PROJECT_VIEW(projectId as string) : null, workspaceSlug && projectId ? USER_PROJECT_VIEW(projectId as string) : null,
@ -227,6 +256,30 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> =
: null : null
); );
const { data: cycleDetails, mutate: mutateCycleDetails } = useSWR(
workspaceSlug && projectId && cycleId ? CYCLE_DETAILS(cycleId as string) : null,
workspaceSlug && projectId && cycleId
? () =>
cyclesService.getCycleDetails(
workspaceSlug.toString(),
projectId.toString(),
cycleId.toString()
)
: null
);
const { data: moduleDetails, mutate: mutateModuleDetails } = useSWR(
workspaceSlug && projectId && moduleId ? MODULE_DETAILS(moduleId.toString()) : null,
workspaceSlug && projectId && moduleId
? () =>
modulesService.getModuleDetails(
workspaceSlug.toString(),
projectId.toString(),
moduleId.toString()
)
: null
);
const setIssueView = useCallback( const setIssueView = useCallback(
(property: TIssueViewOptions) => { (property: TIssueViewOptions) => {
dispatch({ dispatch({
@ -352,9 +405,8 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> =
const setFilters = useCallback( const setFilters = useCallback(
(property: Partial<IIssueFilterOptions>, saveToServer = true) => { (property: Partial<IIssueFilterOptions>, saveToServer = true) => {
Object.keys(property).forEach((key) => { Object.keys(property).forEach((key) => {
if (property[key as keyof typeof property]?.length === 0) { if (property[key as keyof typeof property]?.length === 0)
property[key as keyof typeof property] = null; property[key as keyof typeof property] = null;
}
}); });
dispatch({ dispatch({
@ -369,22 +421,53 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> =
if (!workspaceSlug || !projectId) return; if (!workspaceSlug || !projectId) return;
mutateMyViewProps((prevData) => { if (cycleId) {
if (!prevData) return prevData; mutateCycleDetails((prevData: any) => {
if (!prevData) return prevData;
return { return {
...prevData, ...prevData,
view_props: {
filters: {
...state.filters,
...property,
},
},
};
}, false);
saveCycleFilters(workspaceSlug.toString(), projectId.toString(), cycleId.toString(), {
view_props: { view_props: {
...state,
filters: { filters: {
...state.filters, ...state.filters,
...property, ...property,
}, },
}, },
}; });
}, false); } else if (moduleId) {
mutateModuleDetails((prevData: any) => {
if (!prevData) return prevData;
if (viewId) { return {
...prevData,
view_props: {
filters: {
...state.filters,
...property,
},
},
};
}, false);
saveModuleFilters(workspaceSlug.toString(), projectId.toString(), moduleId.toString(), {
view_props: {
filters: {
...state.filters,
...property,
},
},
});
} else if (viewId) {
mutateViewDetails((prevData: any) => { mutateViewDetails((prevData: any) => {
if (!prevData) return prevData; if (!prevData) return prevData;
return { return {
@ -396,13 +479,28 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> =
}; };
}, false); }, false);
if (saveToServer) if (saveToServer)
sendFilterDataToServer(workspaceSlug as string, projectId as string, viewId as string, { saveViewFilters(workspaceSlug as string, projectId as string, viewId as string, {
query_data: { query_data: {
...state.filters, ...state.filters,
...property, ...property,
}, },
}); });
} else if (saveToServer) } else {
mutateMyViewProps((prevData) => {
if (!prevData) return prevData;
return {
...prevData,
view_props: {
...state,
filters: {
...state.filters,
...property,
},
},
};
}, false);
saveDataToServer(workspaceSlug as string, projectId as string, { saveDataToServer(workspaceSlug as string, projectId as string, {
...state, ...state,
filters: { filters: {
@ -410,8 +508,20 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> =
...property, ...property,
}, },
}); });
}
}, },
[projectId, workspaceSlug, state, mutateMyViewProps, viewId, mutateViewDetails] [
projectId,
workspaceSlug,
state,
mutateMyViewProps,
cycleId,
mutateCycleDetails,
moduleId,
mutateModuleDetails,
viewId,
mutateViewDetails,
]
); );
const setNewDefaultView = useCallback(() => { const setNewDefaultView = useCallback(() => {
@ -439,11 +549,17 @@ export const IssueViewContextProvider: React.FC<{ children: React.ReactNode }> =
payload: { payload: {
...myViewProps?.view_props, ...myViewProps?.view_props,
filters: { filters: {
...(viewId ? viewDetails?.query_data : myViewProps?.view_props?.filters), ...(cycleId
? cycleDetails?.view_props.filters
: moduleId
? moduleDetails?.view_props.filters
: viewId
? viewDetails?.query_data
: myViewProps?.view_props?.filters),
} as any, } as any,
}, },
}); });
}, [myViewProps, viewDetails, viewId]); }, [myViewProps, cycleId, cycleDetails, moduleId, moduleDetails, viewId, viewDetails]);
return ( return (
<issueViewContext.Provider <issueViewContext.Provider

View File

@ -115,7 +115,7 @@ class ProjectCycleServices extends APIService {
workspaceSlug: string, workspaceSlug: string,
projectId: string, projectId: string,
cycleId: string, cycleId: string,
data: any data: Partial<ICycle>
): Promise<any> { ): Promise<any> {
return this.patch( return this.patch(
`/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/`, `/api/workspaces/${workspaceSlug}/projects/${projectId}/cycles/${cycleId}/`,

View File

@ -53,7 +53,11 @@ class ProjectIssuesServices extends APIService {
}); });
} }
async getModuleDetails(workspaceSlug: string, projectId: string, moduleId: string): Promise<any> { async getModuleDetails(
workspaceSlug: string,
projectId: string,
moduleId: string
): Promise<IModule> {
return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/`) return this.get(`/api/workspaces/${workspaceSlug}/projects/${projectId}/modules/${moduleId}/`)
.then((response) => response?.data) .then((response) => response?.data)
.catch((error) => { .catch((error) => {

View File

@ -1,4 +1,12 @@
import type { IUser, IIssue, IProject, IProjectLite, IWorkspace, IWorkspaceLite } from "types"; import type {
IUser,
IIssue,
IProject,
IProjectLite,
IWorkspace,
IWorkspaceLite,
IIssueFilterOptions,
} from "types";
export interface ICycle { export interface ICycle {
backlog_issues: number; backlog_issues: number;
@ -21,6 +29,9 @@ export interface ICycle {
unstarted_issues: number; unstarted_issues: number;
updated_at: Date; updated_at: Date;
updated_by: string; updated_by: string;
view_props: {
filters: IIssueFilterOptions;
};
workspace: string; workspace: string;
workspace_detail: IWorkspaceLite; workspace_detail: IWorkspaceLite;
} }

View File

@ -6,6 +6,7 @@ import type {
IWorkspace, IWorkspace,
IWorkspaceLite, IWorkspaceLite,
IProjectLite, IProjectLite,
IIssueFilterOptions,
} from "types"; } from "types";
export interface IModule { export interface IModule {
@ -45,6 +46,9 @@ export interface IModule {
unstarted_issues: number; unstarted_issues: number;
updated_at: Date; updated_at: Date;
updated_by: string; updated_by: string;
view_props: {
filters: IIssueFilterOptions;
};
workspace: string; workspace: string;
workspace_detail: IWorkspaceLite; workspace_detail: IWorkspaceLite;
} }