fork refine

This commit is contained in:
Stefan Pejcic
2024-02-05 10:23:04 +01:00
parent 3fffde9a8f
commit 8496a83edb
3634 changed files with 715528 additions and 2 deletions

View File

@@ -0,0 +1,6 @@
import { IUndoableQueue } from "../../interfaces";
export interface IUndoableQueueContext {
notifications: IUndoableQueue[];
notificationDispatch: React.Dispatch<any>;
}

View File

@@ -0,0 +1,5 @@
export enum ActionTypes {
ADD = "ADD",
REMOVE = "REMOVE",
DECREASE_NOTIFICATION_SECOND = "DECREASE_NOTIFICATION_SECOND",
}

View File

@@ -0,0 +1,86 @@
import * as React from "react";
import { act, waitFor } from "@test";
import { renderHook } from "@testing-library/react";
import { undoableQueueReducer } from "./undoableQueueContext";
describe("Notification Reducer", () => {
const notificationDispatch = jest.fn();
const providerProps = {
notifications: [
{
id: "1",
resource: "posts",
seconds: 5000,
isRunning: true,
},
],
notificationDispatch: notificationDispatch,
};
it("should render notification item with ADD action", () => {
const { result } = renderHook(() =>
React.useReducer(undoableQueueReducer, []),
);
const [, dispatch] = result.current;
act(() => {
dispatch({ type: "ADD", payload: providerProps.notifications[0] });
});
const [state] = result.current;
expect(state).toEqual([
{
id: "1",
resource: "posts",
seconds: 5000,
isRunning: true,
},
]);
});
it("remove notification item with DELETE action", async () => {
const { result } = renderHook(() =>
React.useReducer(undoableQueueReducer, providerProps.notifications),
);
const [, dispatch] = result.current;
act(() => {
dispatch({
type: "REMOVE",
payload: providerProps.notifications[0],
});
});
const [state] = result.current;
expect(state).toEqual([]);
});
it("decrease notification item by 1 second with DECREASE_NOTIFICATION_SECOND action", async () => {
const { result } = renderHook(() =>
React.useReducer(undoableQueueReducer, providerProps.notifications),
);
const [, dispatch] = result.current;
act(() => {
dispatch({
type: "DECREASE_NOTIFICATION_SECOND",
payload: {
id: providerProps.notifications[0].id,
seconds: providerProps.notifications[0].seconds,
resource: providerProps.notifications[0].resource,
},
});
});
const [state] = result.current;
expect(state[0].seconds).toEqual(
providerProps.notifications[0].seconds - 1000,
);
});
});

View File

@@ -0,0 +1,5 @@
export { ActionTypes } from "./actionTypes";
export {
UndoableQueueContextProvider,
UndoableQueueContext,
} from "./undoableQueueContext";

View File

@@ -0,0 +1,83 @@
import React, { ReactNode, useReducer } from "react";
import isEqual from "lodash/isEqual";
import { UndoableQueue } from "@components";
import { IUndoableQueue, IUndoableQueueContext } from "../../interfaces";
import { ActionTypes } from "./actionTypes";
export const UndoableQueueContext = React.createContext<IUndoableQueueContext>({
notifications: [],
notificationDispatch: () => false,
});
const initialState: IUndoableQueue[] = [];
export const undoableQueueReducer = (state: IUndoableQueue[], action: any) => {
switch (action.type) {
case ActionTypes.ADD:
const newState = state.filter(
(notificationItem: IUndoableQueue) => {
return !(
isEqual(notificationItem.id, action.payload.id) &&
notificationItem.resource == action.payload.resource
);
},
);
return [
...newState,
{
...action.payload,
isRunning: true,
},
];
case ActionTypes.REMOVE:
return state.filter(
(notificationItem: IUndoableQueue) =>
!(
isEqual(notificationItem.id, action.payload.id) &&
notificationItem.resource == action.payload.resource
),
);
case ActionTypes.DECREASE_NOTIFICATION_SECOND:
return state.map((notificationItem: IUndoableQueue) => {
if (
isEqual(notificationItem.id, action.payload.id) &&
notificationItem.resource == action.payload.resource
) {
return {
...notificationItem,
seconds: action.payload.seconds - 1000,
};
}
return notificationItem;
});
default:
return state;
}
};
export const UndoableQueueContextProvider: React.FC<{
children: ReactNode;
}> = ({ children }) => {
const [notifications, notificationDispatch] = useReducer(
undoableQueueReducer,
initialState,
);
const notificationData = { notifications, notificationDispatch };
return (
<UndoableQueueContext.Provider value={notificationData}>
{children}
{typeof window !== "undefined" &&
notifications.map((notification) => (
<UndoableQueue
key={`${notification.id}-${notification.resource}-queue`}
notification={notification}
/>
))}
</UndoableQueueContext.Provider>
);
};