plane/web/contexts/workspace-view-context.tsx

236 lines
8.3 KiB
TypeScript
Raw Normal View History

import { createContext, useEffect, useState } from "react";
// next imports
import { useRouter } from "next/router";
// swr
import useSWR, { KeyedMutator } from "swr";
// services
import workspaceService from "services/workspace.service";
// types
import { IIssue, IWorkspaceGlobalViewProps } from "types";
import { IWorkspaceView } from "types/workspace-views";
// fetch-keys
import { WORKSPACE_VIEW_DETAILS, WORKSPACE_VIEW_ISSUES } from "constants/fetch-keys";
export interface IWorkspaceViewContext {
params: any;
view: IWorkspaceView | undefined;
viewLoading: boolean;
viewIssues: IIssue[];
mutateViewIssues: KeyedMutator<any>;
viewIssueLoading: boolean;
filters: IWorkspaceGlobalViewProps;
handleFilters: (
filterType: "filters" | "display_filters" | "display_properties",
payload: { [key: string]: any },
saveFiltersToServer?: boolean
) => void;
}
export const WorkspaceIssueViewContext = createContext<IWorkspaceViewContext | undefined>(
undefined
);
export const initialState: IWorkspaceGlobalViewProps = {
filters: {
assignees: null,
created_by: null,
labels: null,
priority: null,
state_group: null,
subscriber: null,
start_date: null,
target_date: null,
project: null,
},
display_filters: {
order_by: "-created_at",
sub_issue: false,
type: null,
layout: "spreadsheet",
},
display_properties: {
assignee: true,
start_date: true,
due_date: true,
key: true,
labels: true,
priority: true,
state: true,
sub_issue_count: true,
attachment_count: true,
link: true,
estimate: true,
created_on: true,
updated_on: true,
},
};
const saveViewFilters = async (
workspaceSlug: string,
viewId: string,
state: IWorkspaceGlobalViewProps
) => {
await workspaceService.updateView(workspaceSlug, viewId, {
query_data: state,
});
};
export const WorkspaceViewProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const router = useRouter();
const { workspaceSlug, viewId } = router.query as {
workspaceSlug: string;
viewId: string;
};
const [filters, setFilters] = useState<IWorkspaceGlobalViewProps>(initialState);
const handleFilters = (
filterType: "filters" | "display_filters" | "display_properties",
payload: { [key: string]: any },
saveFiltersToServer?: boolean
) => {
const updatedFilterPayload = {
...filters,
[filterType]: {
...filters[filterType],
...payload,
},
};
setFilters(() => updatedFilterPayload);
if (saveFiltersToServer) saveViewFilters(workspaceSlug, viewId, updatedFilterPayload);
};
const computedFilter = (filters: any) => {
const computedFilters: any = {};
Object.keys(filters).map((key) => {
if (filters[key] != undefined)
computedFilters[key] =
typeof filters[key] === "string" || typeof filters[key] === "boolean"
? filters[key]
: filters[key].join(",");
});
return computedFilters;
};
const computedParams = (filters: any) => {
const params: any = {
assignees: (filters && filters?.filters?.assignees) || undefined,
created_by: (filters && filters?.filters?.created_by) || undefined,
labels: (filters && filters?.filters?.labels) || undefined,
priority: (filters && filters?.filters?.priority) || undefined,
state_group: (filters && filters?.filters?.state_group) || undefined,
subscriber: (filters && filters?.filters?.subscriber) || undefined,
start_date: (filters && filters?.filters?.start_date) || undefined,
target_date: (filters && filters?.filters?.target_date) || undefined,
project: (filters && filters?.filters?.project) || undefined,
order_by: (filters && filters?.display_filters?.order_by) || "-created_at",
sub_issue: (filters && filters?.display_filters?.sub_issue) || false,
type: filters && filters?.display_filters?.type,
};
return params;
};
const params: any = {
assignees: filters?.filters.assignees ? filters?.filters?.assignees.join(",") : undefined,
created_by: filters?.filters.created_by ? filters?.filters?.created_by.join(",") : undefined,
labels: filters?.filters.labels ? filters?.filters?.labels.join(",") : undefined,
priority: filters?.filters.priority ? filters?.filters?.priority.join(",") : undefined,
state_group: filters?.filters.state_group ? filters?.filters?.state_group.join(",") : undefined,
subscriber: filters?.filters.subscriber ? filters?.filters?.subscriber.join(",") : undefined,
start_date: filters?.filters.start_date ? filters?.filters?.start_date.join(",") : undefined,
target_date: filters?.filters.target_date ? filters?.filters?.target_date.join(",") : undefined,
project: filters?.filters.project ? filters?.filters?.project.join(",") : undefined,
order_by: filters?.display_filters?.order_by
? filters?.display_filters?.order_by
: "-created_at",
sub_issue: filters?.display_filters?.sub_issue ? filters?.display_filters?.sub_issue : false,
type: filters?.display_filters?.type ? filters?.display_filters?.type : undefined,
layout: filters?.display_filters?.layout ? filters?.display_filters?.layout : undefined,
};
const { data: view, isLoading: viewLoading } = useSWR(
workspaceSlug && viewId ? WORKSPACE_VIEW_DETAILS(viewId.toString()) : null,
workspaceSlug && viewId
? () => workspaceService.getViewDetails(workspaceSlug.toString(), viewId.toString())
: null
);
const {
data: viewIssues,
mutate: mutateViewIssues,
isLoading: viewIssueLoading,
} = useSWR(
workspaceSlug && view && viewId && filters
? WORKSPACE_VIEW_ISSUES(viewId.toString(), params)
: null,
workspaceSlug && view && viewId
? () =>
workspaceService.getViewIssues(
workspaceSlug.toString(),
computedFilter(computedParams(filters))
)
: null
);
useEffect(() => {
if (view && view?.query_data) {
const payload = {
filters: {
...view?.query_data?.filters,
assignees: view?.query_data?.filters?.assignees || null,
created_by: view?.query_data?.filters?.created_by || null,
labels: view?.query_data?.filters?.labels || null,
priority: view?.query_data?.filters?.priority || null,
state_group: view?.query_data?.filters?.state_group || null,
subscriber: view?.query_data?.filters?.subscriber || null,
start_date: view?.query_data?.filters?.start_date || null,
target_date: view?.query_data?.filters?.target_date || null,
project: view?.query_data?.filters?.project || null,
},
display_filters: {
...view?.query_data?.display_filters,
order_by: view?.query_data?.display_filters?.order_by || "-created_at",
sub_issue: view?.query_data?.display_filters?.sub_issue || true,
type: view?.query_data?.display_filters?.type || null,
},
display_properties: {
...view?.query_data?.display_properties,
assignee: view?.query_data?.display_properties?.assignee || true,
start_date: view?.query_data?.display_properties?.start_date || true,
due_date: view?.query_data?.display_properties?.due_date || true,
key: view?.query_data?.display_properties?.key || true,
labels: view?.query_data?.display_properties?.labels || true,
priority: view?.query_data?.display_properties?.priority || true,
state: view?.query_data?.display_properties?.state || true,
sub_issue_count: view?.query_data?.display_properties?.sub_issue_count || true,
attachment_count: view?.query_data?.display_properties?.attachment_count || true,
link: view?.query_data?.display_properties?.link || true,
estimate: view?.query_data?.display_properties?.estimate || true,
created_on: view?.query_data?.display_properties?.created_on || true,
updated_on: view?.query_data?.display_properties?.updated_on || true,
},
};
setFilters(payload);
}
}, [view, setFilters]);
return (
<WorkspaceIssueViewContext.Provider
value={{
params,
view,
viewLoading,
viewIssues,
mutateViewIssues,
viewIssueLoading,
filters,
handleFilters,
}}
>
{children}
</WorkspaceIssueViewContext.Provider>
);
};