plane/apps/app/contexts/inbox-view-context.tsx
sriram veeraghanta e1ae0d3b56
feat : Tiptap integration (#1832)
* remirror instances commented out to avoid prosemirror conflicts

* styles migrated for remirror to tiptap transition

* added bubblemenu support with extensions

* fixed css for task lists and code with syntax highlighting

* added support for slash command

* fixed bubble menu to match styles and added better seperation in UI

* saving with debounce logic added and it's stored in backend

* added migration support by updating to html

* Image uploads done

* improved file structure and delete image function implemented

* Integrated tiptap with Issue Modal

* added additional props and Tiptap Integration with Comments

* added tiptap integration with user activity feeds

* added ref control support and bubble menu support for readonly editor

* added tiptap support for plane pages

* added tiptap support to gpt assistant modal (yet to be tested)

* removed remirror instances and cleaned up code

* improved code structure for extracting props in Tiptap

* fixing ts errors for next build

* fixing node ts error for Horizontal Rule

* added ts fix for node types

* temp fix

* temp fix

* added min height for issue description in modal

* added resolutions to prosemirror-model version

* trying pnpm overrides

* explicitly added prosemirror deps

* bugfixes

* removed extra gap at the top and moved saved indicator to the bottom

* fix: slash command scroll position

* chore: update custom css variables

* matched theme colours

* fixed gpt-assistant modal

* updated yarn lock

* added debounced updates for the title and removed saved state after timeout

* added css animations for saved state

* build fixes and remove remirror instances

* minor commenting fixes

---------

Co-authored-by: Palanikannan1437 <73993394+Palanikannan1437@users.noreply.github.com>
Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
2023-08-15 15:04:46 +05:30

198 lines
4.4 KiB
TypeScript

import { createContext, useCallback, useEffect, useReducer } from "react";
import { useRouter } from "next/router";
import useSWR from "swr";
// components
import ToastAlert from "components/toast-alert";
// services
import inboxServices from "services/inbox.service";
// types
import { IInboxFilterOptions } from "types";
// fetch-keys
import { INBOX_DETAILS } from "constants/fetch-keys";
export const inboxViewContext = createContext<ContextType>({} as ContextType);
type InboxViewProps = {
filters: IInboxFilterOptions;
};
type ReducerActionType = {
type: "REHYDRATE_THEME" | "SET_FILTERS";
payload?: Partial<InboxViewProps>;
};
type ContextType = InboxViewProps & {
setFilters: (filters: Partial<IInboxFilterOptions>) => void;
clearAllFilters: () => void;
};
type StateType = {
filters: IInboxFilterOptions;
};
type ReducerFunctionType = (state: StateType, action: ReducerActionType) => StateType;
export const initialState: StateType = {
filters: {
priority: null,
inbox_status: null,
},
};
export const reducer: ReducerFunctionType = (state, action) => {
const { type, payload } = action;
switch (type) {
case "REHYDRATE_THEME": {
return { ...initialState, ...payload };
}
case "SET_FILTERS": {
const newState = {
...state,
filters: {
...state.filters,
...payload?.filters,
},
};
return {
...state,
...newState,
};
}
}
};
const saveDataToServer = async (
workspaceSlug: string,
projectId: string,
inboxId: string,
state: any
) => {
await inboxServices.patchInbox(workspaceSlug, projectId, inboxId, {
view_props: state,
});
};
export const InboxViewContextProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
const router = useRouter();
const { workspaceSlug, projectId, inboxId } = router.query;
const { data: inboxDetails, mutate: mutateInboxDetails } = useSWR(
workspaceSlug && projectId && inboxId ? INBOX_DETAILS(inboxId.toString()) : null,
workspaceSlug && projectId && inboxId
? () =>
inboxServices.getInboxById(
workspaceSlug.toString(),
projectId.toString(),
inboxId.toString()
)
: null
);
const setFilters = useCallback(
(property: Partial<IInboxFilterOptions>) => {
Object.keys(property).forEach((key) => {
if (property[key as keyof typeof property]?.length === 0)
property[key as keyof typeof property] = null;
});
dispatch({
type: "SET_FILTERS",
payload: {
filters: {
...state.filters,
...property,
},
},
});
if (!workspaceSlug || !projectId || !inboxId) return;
const newViewProps = {
...state,
filters: {
...state.filters,
...property,
},
};
mutateInboxDetails((prevData: any) => {
if (!prevData) return prevData;
return {
...prevData,
view_props: newViewProps,
};
}, false);
saveDataToServer(
workspaceSlug.toString(),
projectId.toString(),
inboxId.toString(),
newViewProps
);
},
[workspaceSlug, projectId, inboxId, mutateInboxDetails, state]
);
const clearAllFilters = useCallback(() => {
dispatch({
type: "SET_FILTERS",
payload: {
filters: { ...initialState.filters },
},
});
if (!workspaceSlug || !projectId || !inboxId) return;
const newViewProps = {
...state,
filters: { ...initialState.filters },
};
mutateInboxDetails((prevData: any) => {
if (!prevData) return prevData;
return {
...prevData,
view_props: newViewProps,
};
}, false);
saveDataToServer(
workspaceSlug.toString(),
projectId.toString(),
inboxId.toString(),
newViewProps
);
}, [inboxId, mutateInboxDetails, projectId, state, workspaceSlug]);
useEffect(() => {
dispatch({
type: "REHYDRATE_THEME",
payload: {
...inboxDetails?.view_props,
},
});
}, [inboxDetails]);
return (
<inboxViewContext.Provider
value={{
filters: state.filters,
setFilters,
clearAllFilters,
}}
>
<ToastAlert />
{children}
</inboxViewContext.Provider>
);
};